Tizen 2.1 base
[platform/core/multimedia/audio-session-manager.git] / src / audio-session-mgr-server.c
1 /*
2  * audio-session-manager
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungbae Shin <seungbae.shin@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 <stdlib.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <sys/ipc.h>
31 #include <sys/select.h>
32 #include <sys/time.h>
33 #include <sys/msg.h>
34 #include <glib.h>
35 #include <glib/gprintf.h>
36 #include <poll.h>
37
38 #include <vconf.h>
39 #include <audio-session-manager.h>
40 #include <asm-log.h>
41 #include <string.h>
42 #include <errno.h>
43
44 #include <sysman.h>
45
46 #ifdef USE_SECURITY
47 #include <security-server.h>
48 #endif
49
50 #include <avsys-audio.h>
51
52 #define HIBERNATION_CHECK_KEY   "memory/hibernation/audio_ready"
53 #define HIBERNATION_READY               1
54 #define USE_SYSTEM_SERVER_PROCESS_MONITORING
55
56 #define SUPPORT_GCF /* currently in use */
57
58 static const ASM_sound_cases_t ASM_sound_case[ASM_PRIORITY_MATRIX_MIN+1][ASM_PRIORITY_MATRIX_MIN+1] =
59 {
60         /*        SP SC SS SO SA,  EP EC ES EO EA,  N C SF EF EU, A VC M */
61                 { 8, 8, 8, 8, 8,  6, 6, 6, 6, 6,  8, 8, 8, 6, 6,  6, 6, 8 },    /* 00 Shared MMPlayer */
62                 { 8, 8, 8, 8, 8,  5, 5, 5, 5, 5,  8, 5, 8, 5, 8,  5, 5, 8 },    /* 01 Shared MMCamcorder */
63                 { 8, 8, 8, 8, 8,  5, 5, 5, 5, 5,  8, 5, 8, 5, 6,  5, 5, 8 },    /* 02 Shared MMSound */
64                 { 8, 8, 8, 8, 8,  5, 5, 5, 5, 5,  8, 5, 8, 5, 6,  5, 5, 8 },    /* 03 Shared OpenAL */
65                 { 8, 8, 8, 8, 8,  5, 5, 5, 5, 5,  8, 5, 8, 5, 8,  5, 5, 8 },    /* 04 Shared AVsystem */
66                 { 6, 6, 6, 6, 6,  6, 6, 6, 6, 6,  8, 8, 6, 6, 6,  6, 6, 8 },    /* 05 Exclusive MMPlayer */
67                 { 5, 5, 5, 5, 5,  5, 5, 5, 5, 5,  8, 5, 5, 5, 8,  5, 5 ,8 },    /* 06 Exclusive MMCamcorder */
68                 { 5, 5, 5, 5, 5,  5, 5, 5, 5, 5,  8, 5, 5, 5, 6,  5, 5, 8 },    /* 07 Exclusive MMSound */
69                 { 5, 5, 5, 5, 5,  5, 5, 5, 5, 5,  8, 5, 5, 5, 6,  5, 5, 8 },    /* 08 Exclusive OpenAL */
70                 { 5, 5, 5, 5, 5,  5, 5, 5, 5, 5,  8, 5, 5, 5, 8,  5, 5, 8 },    /* 09 Exclusive AVsystem */
71                 { 8, 8, 8, 8, 8,  8, 8, 8, 8, 8,  8, 5, 8, 8, 8,  5, 5, 8 },    /* 10 Notify */
72                 { 1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  8, 0, 1, 1, 8,  8, 1, 8 },    /* 11 Call */
73                 { 8, 8, 8, 8, 8,  5, 5, 5, 5, 5,  8, 5, 5, 5, 8,  5, 5, 8 },    /* 12 Shared FMradio */
74                 { 5, 5, 5, 5, 5,  5, 5, 5, 5, 5,  8, 5, 5, 5, 8,  5, 5, 8 },    /* 13 Exclusive FMradio */
75                 { 8, 8, 8, 8, 8,  8, 8, 8, 8, 8,  8, 8, 8, 8, 8,  8, 8, 8 },    /* 14 Earjack Unplug */
76                 { 1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  8, 5, 1, 1, 8,  8, 5, 8 },    /* 15 Alarm */
77                 { 1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  8, 1, 1, 1, 8,  8, 0, 8 },    /* 16 Video Call */
78                 { 8, 8, 8, 8, 8,  8, 8, 8, 8, 8,  8, 8, 8, 8, 8,  8, 8, 8 },    /* 17 Monitor */
79 };
80
81 typedef struct _list
82 {
83         long int                                instance_id;
84         int                                     sound_handle;
85         ASM_sound_events_t              sound_event;
86         ASM_sound_states_t              sound_state;
87         ASM_resume_states_t             need_resume;
88         ASM_resource_t                  mm_resource;
89         avsys_audio_playing_devcie_t    device_when_interrupted;
90         unsigned short                  monitor_active;
91         unsigned short                  monitor_dirty;
92         struct _list                    *next;
93 } asm_instance_list_t;
94
95 asm_instance_list_t *head_list, *tail_list;
96
97 int asm_snd_msgid;
98 int asm_rcv_msgid;
99 int asm_cb_msgid;
100 ASM_msg_lib_to_asm_t asm_rcv_msg;
101 ASM_msg_asm_to_lib_t asm_snd_msg;
102 ASM_msg_asm_to_cb_t asm_cb_msg;
103
104 bool asm_is_send_msg_to_cb = false;
105
106 #ifdef SUPPORT_GCF
107 #define GCF_DEFAULT     0
108 int is_gcf = GCF_DEFAULT;
109 #endif
110
111 unsigned int g_sound_status_pause = 0;
112 unsigned int g_sound_status_playing = 0;
113
114 #define SERVER_HANDLE_MAX_COUNT 256
115
116 static const char* ASM_sound_events_str[] =
117 {
118         "SHARE_MMPLAYER",
119         "SHARE_MMCAMCORDER",
120         "SHARE_MMSOUND",
121         "SHARE_OPENAL",
122         "SHARE_AVSYSTEM",
123         "EXCLUSIVE_MMPLAYER",
124         "EXCLUSIVE_MMCAMCORDER",
125         "EXCLUSIVE_MMSOUND",
126         "EXCLUSIVE_OPENAL",
127         "EXCLUSIVE_AVSYSTEM",
128         "NOTIFY",
129         "CALL",
130         "SHARE_FMRADIO",
131         "EXCLUSIVE_FMRADIO",
132         "EARJACK_UNPLUG",
133         "ALARM",
134         "VIDEOCALL",
135         "MONITOR"
136 };
137
138 static const char* ASM_sound_state_str[] =
139 {
140         "STATE_NONE",
141         "STATE_PLAYING",
142         "STATE_WAITING",
143         "STATE_STOP",
144         "STATE_PAUSE",
145         "STATE_PAUSE_BY_APP",
146         "STATE_ALTER_PLAYING"
147 };
148
149
150 static const char* ASM_sound_request_str[] =
151 {
152         "REQUEST_REGISTER",
153         "REQUEST_UNREGISTER",
154         "REQUEST_GETSTATE",
155         "REQUEST_GETMYSTATE",
156         "REQUEST_SETSTATE",
157         "REQUEST_EMEGENT_EXIT",
158         "REQUEST_DUMP"
159 };
160
161
162 static const char* ASM_sound_cases_str[] =
163 {
164         "CASE_NONE",
165         "CASE_1PLAY_2STOP",
166         "CASE_1PLAY_2ALTER_PLAY",
167         "CASE_1PLAY_2WAIT",
168         "CASE_1ALTER_PLAY_2PLAY",
169         "CASE_1STOP_2PLAY",
170         "CASE_1PAUSE_2PLAY",
171         "CASE_1VIRTUAL_2PLAY",
172         "CASE_1PLAY_2PLAY_MIX"
173 };
174
175 static const char* ASM_sound_resume_str[] =
176 {
177                 "NO-RESUME",
178                 "RESUME"
179 };
180
181
182 static const char* ASM_sound_command_str[] =
183 {
184         "CMD_NONE",
185         "CMD_WAIT",
186         "CMD_PLAY",
187         "CMD_STOP",
188         "CMD_PAUSE",
189         "CMD_RESUME",
190 };
191
192 #define ASM_SND_MSG_SET(asm_snd_msg, x_alloc_handle, x_cmd_handle, x_result_sound_command, x_result_sound_state) \
193 do { \
194         asm_snd_msg.data.alloc_handle                   = x_alloc_handle;                       \
195         asm_snd_msg.data.cmd_handle                     = x_cmd_handle;                         \
196         asm_snd_msg.data.result_sound_command   = x_result_sound_command;       \
197         asm_snd_msg.data.result_sound_state     = x_result_sound_state;         \
198 } while (0)
199
200 void selectSleep(int secs)
201 {
202         struct timeval timeout;
203         timeout.tv_sec = (secs < 1 || secs > 10) ? 3 : secs;
204         timeout.tv_usec = 0;
205         select(0, NULL, NULL, NULL, &timeout);
206         return;
207 }
208
209
210 gboolean __find_clean_monitor_handle(int instance_id, int *handle)
211 {
212         asm_instance_list_t *temp_list = head_list;
213         int lhandle = -1;
214
215         while (temp_list->next != tail_list) {
216                 if (temp_list->instance_id == instance_id && temp_list->sound_event == ASM_EVENT_MONITOR) {
217                         if (temp_list->monitor_dirty == 0) {
218                                 lhandle = temp_list->sound_handle;
219                         }
220                         break;
221                 }
222                 temp_list = temp_list->next;
223         }
224         if (lhandle == -1) {
225                 return FALSE;
226         } else {
227                 *handle = lhandle;
228                 return TRUE;
229         }
230 }
231
232 void __update_monitor_active(long int instance_id)
233 {
234         asm_instance_list_t *temp_list = head_list;
235         asm_instance_list_t *monitor_list = NULL;
236         unsigned short active = 0;
237         asm_info("[ASM_Server] %s\n",__func__);
238
239         while (temp_list->next != tail_list) {
240                 if (temp_list->instance_id == instance_id && temp_list->sound_event == ASM_EVENT_MONITOR) {
241                         /* backup monitor pointer */
242                         monitor_list = temp_list;
243                         break;
244                 }
245                 temp_list = temp_list->next;
246         }
247         if (NULL == monitor_list) {
248                 asm_warning("[ASM_Server] %s : No monitor instance for %d\n",__func__, instance_id);
249                 return;
250         }
251
252         temp_list = head_list;
253         while (temp_list->next != tail_list) {
254                 if (temp_list->instance_id == instance_id && temp_list->sound_event != ASM_EVENT_MONITOR) {
255                         if (ASM_STATE_PLAYING == temp_list->sound_state) {
256                                 active = 1;
257                                 break;
258                         }
259                 }
260                 temp_list = temp_list->next;
261         }
262
263         monitor_list->monitor_active = active;
264 }
265
266 void __set_all_monitor_clean()
267 {
268         asm_instance_list_t *temp_list = head_list;
269
270         while (temp_list->next != tail_list) {
271                 if (temp_list->sound_event == ASM_EVENT_MONITOR) {
272                         temp_list->monitor_dirty = 0;
273                 }
274                 temp_list = temp_list->next;
275         }
276 }
277
278 void __set_monitor_dirty(long int instance_id)
279 {
280         asm_instance_list_t *temp_list = head_list;
281
282         while (temp_list->next != tail_list) {
283                 if (temp_list->instance_id == instance_id && temp_list->sound_event == ASM_EVENT_MONITOR) {
284                         temp_list->monitor_dirty = 1;
285                         break;
286                 }
287                 temp_list = temp_list->next;
288         }
289 }
290
291 /* callback without retcb */
292 void __do_callback_wo_retcb(int instance_id,int handle,int command)
293 {
294         int fd_ASM = 0, cur_handle = 0;
295         char *filename = g_strdup_printf("/tmp/ASM.%d.%d", instance_id, handle);
296
297         if ((fd_ASM = open(filename,O_WRONLY|O_NONBLOCK)) < 0) {
298                 asm_info("[ASM_Server][CallCB] %s open error",filename);
299                 g_free(filename);
300                 return;
301         }
302         cur_handle = (unsigned int)(handle |(command << 4));
303         if (write(fd_ASM, (void *)&cur_handle, sizeof(cur_handle)) < 0) {
304                 asm_info("[ASM_Server][CallCB] %s write error",filename);
305                 g_free(filename);
306                 return;
307         }
308         close(fd_ASM);
309         g_free(filename);
310         selectSleep(2); /* if return immediately bad sound occur */
311 }
312
313
314 int __do_callback(int instance_id,int handle,int command, ASM_event_sources_t event_src)
315 {
316         char *filename = NULL;
317         char *filename2 = NULL;
318         struct timeval time;
319         int starttime = 0;
320         int endtime = 0;
321         int fd=0,nread = 0;
322         int fd_ASM = 0, cur_handle = 0;
323         int buf = 0;
324         struct pollfd pfd;
325         int pret = 0;
326         int pollingTimeout = 7000;
327
328         asm_info("[ASM_Server] __do_callback for pid(%d) handle(%d)\n", instance_id, handle);
329
330         /* Set start time */
331         gettimeofday(&time, NULL);
332         starttime = time.tv_sec * 1000000 + time.tv_usec;
333
334         /**************************************
335          *
336          * Open callback cmd pipe
337          *
338          **************************************/
339         filename = g_strdup_printf("/tmp/ASM.%d.%d", instance_id, handle);
340         if ((fd_ASM = open(filename, O_WRONLY|O_NONBLOCK)) < 0) {
341                 asm_error("[ASM_Server][CallCB] %s open error\n", filename);
342                 goto fail;
343         }
344
345         /******************************************
346          *
347          * Open callback result pipe
348          * before writing callback cmd to pipe
349          *
350          ******************************************/
351         filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", instance_id, handle);
352         if ((fd=open(filename2,O_RDONLY|O_NONBLOCK))== -1) {
353                 char str_error[256];
354                 strerror_r (errno, str_error, sizeof(str_error));
355                 asm_error("[ASM_Server][RETCB] Fail to open fifo (%s)\n", str_error);
356                 goto fail;
357         }
358         asm_info("[ASM_Server] open return cb %s\n", filename2);
359
360
361         /*******************************************
362          * Write Callback msg
363          *******************************************/
364         cur_handle = (unsigned int)((0x0000ffff & handle) |(command << 16) | (event_src << 24));
365         if (write(fd_ASM, (void *)&cur_handle, sizeof(cur_handle)) < 0) {
366                 asm_error("[ASM_Server][CallCB] %s write error\n", filename);
367                 goto fail;
368         }
369         /**************************************
370          *
371          * Close callback cmd pipe
372          *
373          **************************************/
374         close(fd_ASM);
375         fd_ASM = -1;
376         g_free(filename);
377         filename = NULL;
378
379         pfd.fd = fd;
380         pfd.events = POLLIN;
381
382         asm_instance_list_t *temp_list = head_list;
383
384
385         /*********************************************
386          *
387          * Wait callback result msg
388          *
389          ********************************************/
390         asm_critical("[ASM_Server][RETCB]wait callback(tid=%d, handle=%d, cmd=%d, timeout=%d)\n", instance_id, handle, command, pollingTimeout);
391         pret = poll(&pfd, 1, pollingTimeout); //timeout 7sec
392         if (pret < 0) {
393                 asm_error("[ASM_Server][RETCB]poll failed (%d)\n", pret);
394                 goto fail;
395         }
396         if (pfd.revents & POLLIN) {
397                 nread=read(fd, (void *)&buf, sizeof(buf));
398         }
399         g_free(filename2);
400         filename2 = NULL;
401
402         /* Calculate endtime and display*/
403         gettimeofday(&time, NULL);
404         endtime = time.tv_sec * 1000000 + time.tv_usec;
405         asm_critical("[ASM_Server][RETCB] ASM_CB_END cbtimelab=%3.3f(second), timeout=%d(milli second) (reciever=%d)\n", ((endtime-starttime)/1000000.), pollingTimeout, instance_id);
406
407         /**************************************
408          *
409          * Close callback result pipe
410          *
411          **************************************/
412         close(fd);
413         fd = -1;
414         asm_info("[ASM_Server][RETCB] Return value 0x%x\n", buf);
415         return buf;
416
417 fail:
418         if (filename) {
419                 g_free (filename);
420                 filename = NULL;
421         }
422         if (filename2) {
423                 g_free (filename2);
424                 filename2 = NULL;
425         }
426         if (fd_ASM != -1) {
427                 close(fd_ASM);
428                 fd_ASM = -1;
429         }
430         if (fd != -1) {
431                 close (fd);
432                 fd = -1;
433         }
434
435         return -1;
436 }
437
438 gboolean __isPlayingNow()
439 {
440         asm_instance_list_t *temp_list = head_list;
441         while (temp_list->next != tail_list) {
442                 if (temp_list->sound_state == ASM_STATE_PLAYING ) {
443                         return TRUE;
444                 }
445
446                 temp_list = temp_list->next;
447         }
448         return FALSE;
449 }
450
451 gboolean __isItPlayingNow(int instance_id, int handle)
452 {
453         asm_instance_list_t *temp_list = head_list;
454         while (temp_list->next != tail_list) {
455                 if (temp_list->instance_id == instance_id && temp_list->sound_handle == handle) {
456                         if (temp_list->sound_state == ASM_STATE_PLAYING) {
457                                 return TRUE;
458                         }
459                 }
460
461                 temp_list = temp_list->next;
462         }
463         return FALSE;
464 }
465
466 void __temp_print_list(char * msg)
467 {
468         asm_instance_list_t *temp_list = head_list;
469         int i = 0;
470
471         if (NULL != msg) {
472                 asm_warning("[ASM_Server] %s\n", msg);
473         }
474         while (temp_list->next != tail_list) {
475                 asm_info("[ASM_Server] List[%02d] ( %5ld, %2d, %-20s, %-20s, %9s, 0x%04x)\n", i, temp_list->instance_id, temp_list->sound_handle,
476                                                                                                 ASM_sound_events_str[temp_list->sound_event],
477                                                                                                 ASM_sound_state_str[temp_list->sound_state],
478                                                                                                 ASM_sound_resume_str[temp_list->need_resume],
479                                                                                                 temp_list->mm_resource);
480                 temp_list = temp_list->next;
481                 i++;
482         }
483 }
484
485 void updatePhoneStatus()
486 {
487         asm_instance_list_t *temp_list = head_list;
488         int i = 0, error = 0;
489
490         g_sound_status_pause = 0;
491         g_sound_status_playing = 0;
492
493         while (temp_list->next != tail_list) {
494                 if (temp_list->sound_state == ASM_STATE_PLAYING) {
495                         if (temp_list->sound_event >= ASM_EVENT_SHARE_MMPLAYER && temp_list->sound_event  < ASM_EVENT_MAX) {
496                                 g_sound_status_playing |= ASM_sound_type[(temp_list->sound_event) + 1].sound_status;
497                         }
498                 } else if (temp_list->sound_state == ASM_STATE_PAUSE ) {
499                         if (temp_list->sound_event >= ASM_EVENT_SHARE_MMPLAYER && temp_list->sound_event < ASM_EVENT_MAX) {
500                                 g_sound_status_pause |= ASM_sound_type[(temp_list->sound_event) + 1].sound_status;
501                         }
502                 }
503                 temp_list = temp_list->next;
504         }
505
506         if (vconf_set_int(SOUND_STATUS_KEY, g_sound_status_playing)) {
507                 asm_info("[ASM_Server[Error = %d][1st try] phonestatus_set \n", error);
508                 if (vconf_set_int(SOUND_STATUS_KEY, g_sound_status_playing)) {
509                         asm_critical("[ASM_Server][Error = %d][2nd try]  phonestatus_set \n", error);
510                 }
511         }
512
513         asm_info("[ASM_Server] soundstatus set to (0x%08x)\n", g_sound_status_playing);
514 }
515
516
517 void __asm_register_list(long int instance_id, int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_resource_t mm_resource)
518 {
519         asm_instance_list_t *temp_list;
520         temp_list = (asm_instance_list_t *)malloc(sizeof(asm_instance_list_t));
521         temp_list->instance_id = instance_id;
522         temp_list->sound_handle = handle;
523         temp_list->sound_event = sound_event;
524         temp_list->sound_state = sound_state;
525         temp_list->need_resume = 0;
526         temp_list->mm_resource = mm_resource;
527         temp_list->monitor_active = 0;
528         temp_list->monitor_dirty = 0;
529         temp_list->device_when_interrupted = AVSYS_AUDIO_ROUTE_DEVICE_UNKNOWN;
530         temp_list->next = head_list;
531         head_list = temp_list;
532
533         __temp_print_list("Register List");
534         updatePhoneStatus();
535 }
536
537 int __asm_unregister_list(int handle)
538 {
539         asm_instance_list_t *temp_list = head_list;
540         asm_instance_list_t *temp_list2 = head_list; 
541         int instance_id = -1;
542
543         asm_info("[ASM_Server] __asm_unregister_list \n");
544
545         while (temp_list->next != tail_list) {
546                 if (temp_list->sound_handle == handle) {
547                         instance_id = temp_list->instance_id;
548                         if (temp_list == head_list)
549                                 head_list = temp_list->next;
550                         else
551                                 temp_list2->next = temp_list->next; 
552                         free(temp_list);
553                         break;
554                 }
555                 temp_list2 = temp_list; 
556                 temp_list = temp_list->next;
557         }
558
559         __temp_print_list("Unregister List for handle");
560         updatePhoneStatus();
561         return instance_id;
562 }
563
564
565 /* -------------------------
566  * if PID exist return true, else return false
567  */
568 gboolean isPIDExist(int pid)
569 {
570         if (pid > 999999 || pid < 2)
571                 return FALSE;
572         gchar *tmp = g_malloc0(25);
573         g_sprintf(tmp, "/proc/%d", pid);
574         if (access(tmp, R_OK)==0) {
575                 g_free(tmp);
576                 return TRUE;
577         }
578         g_free(tmp);
579         return FALSE;
580 }
581
582
583 /* -------------------------
584  *
585  */
586 void __check_dead_process()
587 {
588         asm_instance_list_t *temp_list = head_list;
589         asm_instance_list_t *temp_list2 = head_list;
590         while (temp_list->next != tail_list) {
591                 if (!isPIDExist(temp_list->instance_id)) {
592                         asm_critical_r("[ASM_Server] PID(%ld) not exist! -> ASM_Server resource of pid(%ld) will be cleared \n", temp_list->instance_id, temp_list->instance_id);
593
594                         if (temp_list == head_list) {
595                                 head_list = temp_list->next;
596                         }
597                         temp_list2->next = temp_list->next;
598                         free(temp_list);
599                 } else {
600                         temp_list2 = temp_list;
601                 }
602                 temp_list = temp_list2->next;
603         }
604         updatePhoneStatus();
605 }
606
607
608
609
610 void emergent_exit(int exit_pid)
611 {
612         asm_instance_list_t *temp_list = head_list;
613         int handle = -1;
614         int instance_id = -1;
615
616         while (temp_list->next != tail_list) {
617                 if (temp_list->instance_id == exit_pid) {
618                         handle = temp_list->sound_handle;
619
620                         instance_id = __asm_unregister_list(handle);
621
622                         if (instance_id != -1) {
623                                 char str_error[256];
624                                 char* filename = g_strdup_printf("/tmp/ASM.%d.%d", instance_id, handle);
625                                 char* filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", instance_id, handle);
626                                 if (!remove(filename)) {
627                                         asm_info("[ASM_Server] remove %s success\n", filename);
628                                 } else {
629                                         strerror_r (errno, str_error, sizeof (str_error));
630                                         asm_error("[ASM_Server] remove %s failed with %s\n", filename, str_error);
631                                 }
632
633                                 if (!remove(filename2)) {
634                                         asm_info("[ASM_Server] remove %s success\n", filename2);
635                                 } else {
636                                         strerror_r (errno, str_error, sizeof (str_error));
637                                         asm_error("[ASM_Server] remove %s failed with %s\n", filename2, str_error);
638                                 }
639
640                                 g_free(filename);
641                                 g_free(filename2);
642                         }
643                         temp_list = head_list;
644                 } else {
645                         temp_list = temp_list->next;
646                 }
647         }
648
649         asm_info("[ASM_Server][EMERGENT_EXIT] complete\n");
650         return;
651 }
652
653
654 int ___reorder_state(ASM_sound_states_t input)
655 {
656         int res = 0;
657
658         switch (input) {
659         case ASM_STATE_IGNORE:
660         case ASM_STATE_NONE:
661                 res = 0;
662                 break;
663         case ASM_STATE_WAITING:
664         case ASM_STATE_STOP:
665                 res = 1;
666                 break;
667         case ASM_STATE_PAUSE:
668         case ASM_STATE_PAUSE_BY_APP:
669                 res = 2;
670                 break;
671         case ASM_STATE_PLAYING:
672                 res = 3;
673                 break;
674         }
675         return res;
676 }
677
678 ASM_sound_states_t __asm_find_process_status(int pid)
679 {
680         asm_instance_list_t *temp_list = head_list;
681         ASM_sound_states_t result_state = ASM_STATE_NONE;
682
683         asm_info("[ASM_Server] __asm_find_process_status for pid %d\n", pid);
684
685         while (temp_list->next != tail_list) {
686                 if (temp_list->instance_id == pid) {
687                         if ( ___reorder_state(temp_list->sound_state) >= ___reorder_state(result_state)) {
688                                 result_state = temp_list->sound_state;
689                         }
690                 }
691                 temp_list = temp_list->next;
692         }
693
694         return result_state;
695 }
696
697 ASM_sound_states_t __asm_find_list(ASM_requests_t request_id, int handle)
698 {
699         asm_instance_list_t *temp_list = head_list;
700
701         asm_info("[ASM_Server] __asm_find_list\n");
702
703         while (temp_list->next != tail_list) {
704                 if ((request_id == ASM_REQUEST_GETSTATE && temp_list->sound_handle == handle)) {
705                         return temp_list->sound_state;
706                 } else {
707                         temp_list = temp_list->next;
708                 }
709         }
710
711         return ASM_STATE_NONE;
712 }
713
714 void __asm_change_state_list(long int instance_id, int handle, ASM_sound_states_t sound_state, ASM_resource_t mm_resource)
715 {
716         asm_instance_list_t *temp_list = head_list;
717         int monitor_handle = -1;
718         asm_info("[ASM_Server] __asm_change_state_list\n");
719         if (sound_state == ASM_STATE_IGNORE) {
720                 asm_info("[ASM_Server] skip update state list %ld-%d\n", instance_id, handle);
721                 return;
722         }
723
724         while (temp_list->next != tail_list) {
725                 if (temp_list->instance_id == instance_id && temp_list->sound_handle == handle) {
726                         temp_list->sound_state = sound_state;
727                         temp_list->mm_resource = mm_resource;
728                         break;
729                 }
730                 temp_list = temp_list->next;
731         }
732         __update_monitor_active(instance_id);
733         updatePhoneStatus();
734 }
735
736 void __asm_change_need_resume_list(long int instance_id, int handle, ASM_resume_states_t need_resume)
737 {
738         asm_instance_list_t *temp_list = head_list;
739         asm_info("[ASM_Server] __asm_change_need_resume_list\n");
740         while (temp_list->next != tail_list) {
741                 if (temp_list->instance_id == instance_id && temp_list->sound_handle == handle) {
742                         temp_list->need_resume = need_resume;
743
744                         if (need_resume == ASM_NEED_RESUME) {
745                                 avsys_audio_playing_devcie_t dev = AVSYS_AUDIO_ROUTE_DEVICE_UNKNOWN;
746                                 if (AVSYS_SUCCESS(avsys_audio_get_playing_device_info(&dev))) {
747                                         temp_list->device_when_interrupted = dev;
748                                 }
749                         }
750                         break;
751                 }
752                 temp_list = temp_list->next;
753         }
754 }
755
756
757 void __asm_create_message_queue()
758 {
759         asm_rcv_msgid = msgget((key_t)2014, 0666 | IPC_CREAT);
760         asm_snd_msgid = msgget((key_t)4102, 0666 | IPC_CREAT);
761         asm_cb_msgid = msgget((key_t)4103, 0666 | IPC_CREAT);
762
763         if (asm_snd_msgid == -1 || asm_rcv_msgid == -1 || asm_cb_msgid == -1) {
764                 asm_critical("[ASM_Server] msgget failed with error: \n");
765                 exit(EXIT_FAILURE);
766         }
767 }
768
769 void __asm_snd_message()
770 {
771         if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) == -1) {
772                 asm_critical("[ASM_Server] msgsnd failed with error %d\n", errno);
773                 exit(EXIT_FAILURE);
774         }
775 }
776
777 void __asm_cb_message()
778 {
779         if (msgsnd(asm_cb_msgid, (void *)&asm_cb_msg, sizeof(asm_cb_msg.data), 0) == -1) {
780                 asm_critical_r("[ASM_Server] msgsnd(Callback msg) failed with error %d\n", errno);
781                 exit(EXIT_FAILURE);
782         }
783 }
784
785 void __asm_rcv_message()
786 {
787         if (msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), 0, 0) == -1) {
788                 asm_critical_r("[ASM_Server] msgrcv failed with error %d\n", errno);
789                 exit(EXIT_FAILURE);
790         }
791 }
792
793 void __asm_get_empty_handle(long int instance_id, int *handle)
794 {
795         asm_instance_list_t *temp_list = head_list;
796         unsigned int i = 0, find_empty = 0, j = 0;
797         char handle_info[SERVER_HANDLE_MAX_COUNT];
798
799         asm_info("[ASM_Server] __asm_make_handle for %ld\n", instance_id);
800         __temp_print_list("current list before get new handle");
801
802         memset(handle_info, 0, sizeof(char) * SERVER_HANDLE_MAX_COUNT);
803
804         while (temp_list->next != tail_list) {
805                 handle_info[temp_list->sound_handle] = 1;
806                 temp_list = temp_list->next;
807         }
808
809         for (i = 0; i < ASM_SERVER_HANDLE_MAX; i++) {
810                 if (handle_info[i] == 0) {
811                         find_empty = 1;
812                         break;
813                 }
814         }
815         if (find_empty && (i != ASM_SERVER_HANDLE_MAX)) {
816                 asm_error_r("[ASM_Server] New handle for %ld is %d\n", instance_id, i);
817                 *handle = i;
818         } else {
819                 asm_error_r("[ASM_Server] Handle is full for pid %ld\n", instance_id);
820                 *handle = -1;
821         }
822
823 }
824
825 void __print_resource(unsigned short resource_status)
826 {
827         if (resource_status == ASM_RESOURCE_NONE)
828                 asm_info("[ASM_Server] resource NONE\n");
829         if (resource_status | ASM_RESOURCE_CAMERA)
830                 asm_info("[ASM_Server] resource CAMERA\n");
831         if (resource_status | ASM_RESOURCE_VIDEO_OVERLAY)
832                 asm_info("[ASM_Server] resource VIDEO OVERLAY\n");
833         if (resource_status | ASM_RESOURCE_HW_ENCORDER)
834                 asm_info("[ASM_Server] resource HW ENCORDER\n");
835         if (resource_status | ASM_RESOURCE_HW_DECORDER)
836                 asm_info("[ASM_Server] resource HW DECORDER\n");
837         if (resource_status | ASM_RESOURCE_RADIO_TUNNER)
838                 asm_info("[ASM_Server] resource RADIO TUNNER\n");
839         if (resource_status | ASM_RESOURCE_TV_TUNNER)
840                 asm_info("[ASM_Server] resource TV TUNNER\n");
841 }
842
843 void __asm_compare_priority_matrix(long int instance_id, int handle, ASM_requests_t request_id,
844                                   ASM_sound_events_t sound_event,ASM_sound_states_t sound_state, ASM_resource_t mm_resource)
845 {
846         int no_conflict_flag = 0;
847
848         /* If nobody is playing now, this means no conflict */
849         if (ASM_STATUS_NONE == g_sound_status_playing) {
850                 asm_info("[ASM_Server] __asm_compare_priority_matrix : No conflict ( No existing Sound )\n");
851
852                 ASM_SND_MSG_SET(asm_snd_msg, handle, -1, ASM_COMMAND_NONE, sound_state);
853
854                 no_conflict_flag = 1;
855         } else { /* Somebody is playing */
856                 asm_instance_list_t *temp_list = head_list;
857                 int updatedflag = 0;
858                 int cb_res = 0;
859                 int update_state = ASM_STATE_NONE;
860
861                 while (temp_list->next != tail_list) {
862                         /* Find who's playing now */
863                         if (temp_list->sound_state == ASM_STATE_PLAYING) {
864                                 /* Found it */
865                                 ASM_sound_states_t current_play_state = temp_list->sound_state;
866                                 ASM_sound_events_t current_play_sound_event = temp_list->sound_event;
867                                 long int current_play_instance_id = temp_list->instance_id;
868                                 int current_play_handle = temp_list->sound_handle;
869                                 ASM_resource_t current_using_resource = temp_list->mm_resource;
870
871                                 if ((current_play_instance_id == instance_id) && (current_play_handle == handle)) {
872                                         asm_warning("[ASM_Server] This is my handle. skip %d %d\n", instance_id, handle);
873                                         temp_list = temp_list->next;
874                                         continue;
875                                 }
876
877                                 /* Request is PLAYING */
878                                 if (sound_state == ASM_STATE_PLAYING) {
879                                         /* Determine sound policy */
880                                         ASM_sound_cases_t sound_case = ASM_sound_case[current_play_sound_event][sound_event];
881
882 #ifdef SUPPORT_GCF
883                                         /* GCF case is exception case */
884                                         /* NOTE : GCF exception case only */
885                                         if ((is_gcf) && (sound_case != ASM_CASE_1PLAY_2PLAY_MIX)) {
886                                                 sound_case = ASM_CASE_1PLAY_2PLAY_MIX;;
887                                         }
888 #endif
889
890                                         asm_critical("[ASM_Server] Conflict policy[%x][%x]: %s\n", current_play_sound_event,sound_event,ASM_sound_cases_str[sound_case]);
891                                         switch (sound_case) {
892                                         case ASM_CASE_1PLAY_2STOP:
893                                         {
894                                                 if (current_play_instance_id == instance_id) {
895                                                         /* PID is policy group.*/
896                                                         asm_info("[ASM_Server] Do not send Stop callback in same pid %ld\n", instance_id);
897                                                 } else {
898                                                         ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_STOP, sound_state);
899                                                         temp_list = tail_list;  /* skip all remain list */
900                                                         break;
901                                                 }
902
903                                                 /* Prepare msg to send */
904                                                 ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
905
906                                                 if (!updatedflag) {
907                                                         if (request_id == ASM_REQUEST_REGISTER){
908                                                                 __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
909                                                         } else {
910                                                                 __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
911                                                         }
912                                                         updatedflag = 1;
913                                                 }
914                                                 break;
915                                         }
916
917                                         case ASM_CASE_1STOP_2PLAY:
918                                         {
919                                                 if (current_play_instance_id == instance_id) {
920                                                         /* PID is policy group. */
921                                                         asm_info("[ASM_Server] Do not send Stop callback in same pid %ld\n", instance_id);
922                                                 } else {
923                                                         ASM_event_sources_t event_src;
924                                                         unsigned short resource_status = current_using_resource & mm_resource;
925
926                                                         /* Determine root cause of conflict */
927                                                         if (resource_status != ASM_RESOURCE_NONE) {
928                                                                 event_src = ASM_EVENT_SOURCE_RESOURCE_CONFLICT;
929                                                         } else {
930                                                                 switch (sound_event) {
931                                                                 case ASM_EVENT_CALL:
932                                                                 case ASM_EVENT_VIDEOCALL:
933                                                                         event_src = ASM_EVENT_SOURCE_CALL_START;
934                                                                         break;
935
936                                                                 case ASM_EVENT_EARJACK_UNPLUG:
937                                                                         event_src = ASM_EVENT_SOURCE_EARJACK_UNPLUG;
938                                                                         break;
939
940                                                                 case ASM_EVENT_ALARM:
941                                                                         event_src = ASM_EVENT_SOURCE_ALARM_START;
942                                                                         break;
943
944                                                                 default:
945                                                                         event_src = ASM_EVENT_SOURCE_OTHER_APP;
946                                                                         break;
947                                                                 }
948                                                         }
949
950                                                         /* Execute callback function for monitor handle */
951                                                         int monitor_handle = -1;
952                                                         if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
953                                                                 cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, event_src);
954                                                                 asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
955                                                                 if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
956                                                                         asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
957                                                                 }
958                                                                 __set_monitor_dirty(current_play_instance_id);
959
960                                                                 /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
961                                                                 if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
962                                                                    && (current_play_state == ASM_STATE_PLAYING)) {
963                                                                         __asm_change_need_resume_list(current_play_instance_id, monitor_handle, ASM_NEED_RESUME);
964                                                                 }
965                                                         }
966
967                                                         /* Execute callback function for worker handle */
968                                                         cb_res = __do_callback(current_play_instance_id,current_play_handle,ASM_COMMAND_STOP, event_src);
969                                                         if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP)
970                                                                 asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
971                                                         asm_warning("[ASM_Server]  __asm_compare_priority_matrix(1STOP_2PLAY) : __do_callback Complete : TID=%ld, handle=%d",
972                                                                                 current_play_instance_id,current_play_handle );
973
974                                                         /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
975                                                         if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
976                                                                 && (current_play_state == ASM_STATE_PLAYING)) {
977                                                                 __asm_change_need_resume_list(current_play_instance_id, current_play_handle, ASM_NEED_RESUME);
978                                                         }
979
980                                                         /* Set state to NONE */
981                                                         __asm_change_state_list(current_play_instance_id, current_play_handle, ASM_STATE_NONE, ASM_RESOURCE_NONE);
982                                                 }
983
984                                                 /* Prepare msg to send */
985                                                 ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
986
987                                                 if (!updatedflag) {
988                                                         if (request_id == ASM_REQUEST_REGISTER) {
989                                                                 __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
990                                                         } else {
991                                                                 __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
992                                                         }
993                                                         updatedflag = 1;
994                                                 }
995                                                 break;
996                                         }
997
998                                         case ASM_CASE_1PAUSE_2PLAY:
999                                         {
1000                                                 ASM_resource_t  update_resource = current_using_resource;
1001                                                 if (current_play_instance_id == instance_id)    {
1002                                                         asm_info("[ASM_Server] Do not send Pause callback in same pid %ld\n", instance_id);
1003                                                 } else {
1004                                                         ASM_event_sources_t event_src;
1005                                                         ASM_sound_commands_t command;
1006
1007                                                         unsigned short resource_status = current_using_resource & mm_resource;
1008                                                         if (resource_status != ASM_RESOURCE_NONE) {
1009                                                                 asm_info("[ASM_Server] resource conflict found 0x%x\n", resource_status);
1010                                                                 event_src = ASM_EVENT_SOURCE_RESOURCE_CONFLICT;
1011                                                                 command = ASM_COMMAND_STOP;
1012                                                         } else {
1013                                                                 switch (sound_event) {
1014                                                                 case ASM_EVENT_CALL:
1015                                                                 case ASM_EVENT_VIDEOCALL:
1016                                                                         event_src = ASM_EVENT_SOURCE_CALL_START;
1017                                                                         break;
1018
1019                                                                 case ASM_EVENT_EARJACK_UNPLUG:
1020                                                                         event_src = ASM_EVENT_SOURCE_EARJACK_UNPLUG;
1021                                                                         break;
1022
1023                                                                 case ASM_EVENT_ALARM:
1024                                                                         event_src = ASM_EVENT_SOURCE_ALARM_START;
1025                                                                         break;
1026
1027                                                                 case ASM_EVENT_SHARE_MMPLAYER:
1028                                                                 case ASM_EVENT_EXCLUSIVE_MMPLAYER:
1029                                                                         if (    current_play_sound_event == ASM_EVENT_SHARE_MMPLAYER ||
1030                                                                                 current_play_sound_event == ASM_EVENT_EXCLUSIVE_MMPLAYER ) {
1031                                                                                 event_src = ASM_EVENT_SOURCE_OTHER_PLAYER_APP;
1032                                                                                 break;
1033                                                                         }
1034
1035                                                                 default:
1036                                                                         event_src = ASM_EVENT_SOURCE_OTHER_APP;
1037                                                                         break;
1038                                                                 }
1039                                                                 command = ASM_COMMAND_PAUSE;
1040                                                         }
1041
1042                                                         /* Execute callback function for monitor handle */
1043                                                         int monitor_handle = -1;
1044                                                         if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
1045                                                                 cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, event_src);
1046                                                                 asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
1047                                                                 if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
1048                                                                         asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
1049                                                                 }
1050                                                                 __set_monitor_dirty(current_play_instance_id);
1051
1052                                                                 /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
1053                                                                 if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
1054                                                                         && (current_play_state == ASM_STATE_PLAYING)) {
1055                                                                         __asm_change_need_resume_list(current_play_instance_id, monitor_handle, ASM_NEED_RESUME);
1056                                                                 }
1057                                                         }
1058
1059                                                         /* Execute callback function for worker handle */
1060                                                         cb_res = __do_callback(current_play_instance_id,current_play_handle,command, event_src);
1061                                                         asm_warning("[ASM_Server]  %s(1PAUSE_2PLAY) : Callback of %s: TID(%ld)\n",
1062                                                                                 __func__,ASM_sound_command_str[command], current_play_instance_id);
1063                                                         /*Change current sound' state when it is in 1Pause_2Play case */
1064                                                         switch (cb_res) {
1065                                                         case ASM_CB_RES_PAUSE:
1066                                                                 update_state = ASM_STATE_PAUSE;
1067                                                                 break;
1068
1069                                                         case ASM_CB_RES_NONE:
1070                                                         case ASM_CB_RES_STOP:
1071                                                                 update_state = ASM_STATE_NONE;
1072                                                                 update_resource = ASM_RESOURCE_NONE;
1073                                                                 break;
1074
1075                                                         case ASM_CB_RES_IGNORE:
1076                                                                 update_state = ASM_STATE_IGNORE;
1077                                                                 break;
1078
1079                                                         default:
1080                                                                 asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
1081                                                                 update_state = ASM_STATE_NONE;
1082                                                                 break;
1083                                                         }
1084
1085                                                         /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
1086                                                         if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
1087                                                                 &&(current_play_state == ASM_STATE_PLAYING)) {
1088                                                                 __asm_change_need_resume_list(current_play_instance_id, current_play_handle, ASM_NEED_RESUME);
1089                                                         }
1090
1091                                                         __asm_change_state_list(current_play_instance_id, current_play_handle, update_state, update_resource);
1092                                                 }
1093
1094                                                 /* Prepare msg to send */
1095                                                 ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
1096
1097                                                 if (!updatedflag) {
1098                                                         if (request_id == ASM_REQUEST_REGISTER) {
1099                                                                 __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
1100                                                         } else {
1101                                                                 __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
1102                                                         }
1103                                                         updatedflag = 1;
1104                                                 }
1105                                                 break;
1106                                         }
1107
1108                                         case ASM_CASE_1PLAY_2PLAY_MIX:
1109                                         {
1110                                                 if (current_play_instance_id == instance_id) {
1111                                                         asm_info("[ASM_Server] Do not send check resource conflict in same pid %ld\n", instance_id);
1112                                                 } else {
1113                                                         /* MIX but need to check resource conflict */
1114                                                         asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix(1PLAY_2PLAY_MIX) :  !!!\n");
1115                                                         ASM_resource_t update_resource = current_using_resource;
1116                                                         unsigned short resource_status = current_using_resource & mm_resource;
1117                                                         if (resource_status) { /* Resouce conflict */
1118                                                                 asm_warning("[ASM_Server] there is system resource conflict 0x%x\n", resource_status);
1119                                                                 __print_resource(resource_status);
1120
1121                                                                 /* Execute callback function for monitor handle */
1122                                                                 int monitor_handle = -1;
1123                                                                 if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
1124                                                                         cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
1125                                                                         if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
1126                                                                                 asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
1127                                                                         }
1128                                                                         asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
1129                                                                         __set_monitor_dirty(current_play_instance_id);
1130
1131                                                                         /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
1132                                                                         if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
1133                                                                                 && (current_play_state == ASM_STATE_PLAYING) ) {
1134                                                                                 __asm_change_need_resume_list(current_play_instance_id, monitor_handle, ASM_NEED_RESUME);
1135                                                                         }
1136                                                                 }
1137
1138                                                                 /* Execute callback function for worker handle */
1139                                                                 /* Stop current resource holding instance */
1140                                                                 cb_res = __do_callback(current_play_instance_id, current_play_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
1141                                                                 asm_warning("[ASM_Server]  __asm_compare_priority_matrix(1PLAY_2PLAY_MIX) : Resource Conflict : TID(%ld)\n",
1142                                                                                         current_play_instance_id);
1143
1144                                                                 /* Change current sound */
1145                                                                 switch (cb_res) {
1146                                                                 case ASM_CB_RES_NONE:
1147                                                                 case ASM_CB_RES_STOP:
1148                                                                         update_state = ASM_STATE_NONE;
1149                                                                         update_resource = ASM_RESOURCE_NONE;
1150                                                                         break;
1151
1152                                                                 case ASM_CB_RES_IGNORE:
1153                                                                         update_state = ASM_STATE_IGNORE;
1154                                                                         break;
1155
1156                                                                 default:
1157                                                                         asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
1158                                                                         update_state = ASM_STATE_NONE;
1159                                                                         break;
1160                                                                 }
1161
1162                                                                 __asm_change_state_list(current_play_instance_id, current_play_handle, update_state, update_resource);
1163                                                         }
1164                                                 }
1165
1166                                                 /* Prepare msg to send */
1167                                                 ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
1168
1169                                                 if (!updatedflag) {
1170                                                         if (request_id == ASM_REQUEST_REGISTER) {
1171                                                                 __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
1172                                                         } else {
1173                                                                 __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
1174                                                         }
1175                                                         updatedflag = 1;
1176                                                 }
1177                                                 break;
1178                                         }
1179
1180                                         default:
1181                                         {
1182                                                 ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_NONE, sound_state);
1183                                                 asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix : ASM_CASE_NONE [It should not be seen] !!!\n");
1184                                                 break;
1185                                         }
1186                                         } /* switch (sound_case) */
1187                                 } else {
1188                                         /* Request was not PLAYING, this means no conflict, just do set */
1189                                         asm_info("[ASM_Server] __asm_compare_priority_matrix : No Conflict (Just Register or Set State) !!!\n");
1190                                         ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_NONE, sound_state);
1191
1192                                         if (sound_state == ASM_STATE_NONE) {
1193                                                 asm_info("[ASM_Server] __asm_compare_priority_matrix(1PLAY_2NONE) : No Conflict !!!\n");
1194                                         } else if (sound_state == ASM_STATE_WAITING) {
1195                                                 asm_info("[ASM_Server] __asm_compare_priority_matrix(1PLAY_2WAIT) : No Conflict !!!\n");
1196                                         }
1197
1198                                         if (!updatedflag) {
1199                                                 if (request_id == ASM_REQUEST_REGISTER) {
1200                                                         __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
1201                                                 } else {
1202                                                         __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
1203                                                 }
1204                                                 updatedflag = 1;
1205                                         }
1206                                 }
1207                         } /* if (temp_list->sound_state == ASM_STATE_PLAYING)  */
1208
1209                         temp_list = temp_list->next;
1210
1211                 } /* while (temp_list->next != tail_list) */
1212
1213                 /* Make all monitor handle dirty flag clean. */
1214                 __set_all_monitor_clean();
1215         }
1216
1217         /* Find if resource confilct exists in case of 1Pause 2Play or 1Stop 2Play */
1218         if (ASM_STATUS_NONE != g_sound_status_pause && mm_resource != ASM_RESOURCE_NONE &&
1219                 (asm_snd_msg.data.result_sound_command == ASM_COMMAND_PLAY || no_conflict_flag)) {
1220                 asm_instance_list_t *temp_list = head_list;
1221                 int cb_res = 0;
1222                 
1223                 while (temp_list->next != tail_list) {
1224                         /* Who is in PAUSE state? */
1225                         if (temp_list->sound_state == ASM_STATE_PAUSE) {
1226                                 /* Found PAUSE state */
1227                                 asm_warning("[ASM_Server] Now list's state is pause. %d %d\n", instance_id, handle);
1228                                 ASM_sound_states_t current_play_state = temp_list->sound_state;
1229                                 ASM_sound_events_t current_play_sound_event = temp_list->sound_event;
1230                                 long int current_play_instance_id = temp_list->instance_id;
1231                                 int current_play_handle = temp_list->sound_handle;
1232                                 ASM_resource_t current_using_resource = temp_list->mm_resource;
1233
1234                                 if ((current_play_instance_id == instance_id) && (current_play_handle == handle)) {
1235                                         if (request_id == ASM_REQUEST_SETSTATE) {
1236                                                 asm_warning("[ASM_Server] Own handle. Pause state change to play. %d %d\n", instance_id, handle);
1237                                                 __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
1238                                         } else {
1239                                                 asm_warning("[ASM_Server] This is my handle. skip %d %d\n", instance_id, handle);
1240                                         }
1241                                         temp_list = temp_list->next;
1242                                         continue;
1243                                 }
1244
1245                                 if (sound_state == ASM_STATE_PLAYING) {
1246                                         ASM_sound_cases_t sound_case = ASM_sound_case[current_play_sound_event][sound_event];
1247
1248                                         asm_critical("[ASM_Server] Conflict policy[%x][%x]: %s\n", current_play_sound_event, sound_event, ASM_sound_cases_str[sound_case]);
1249                                         switch (sound_case) {
1250                                         case ASM_CASE_1PAUSE_2PLAY:
1251                                         case ASM_CASE_1STOP_2PLAY:
1252                                         {
1253                                                 if (current_play_instance_id == instance_id) {
1254                                                         //PID is policy group.
1255                                                         asm_info("[ASM_Server] Do not send Stop callback in same pid %ld\n", instance_id);
1256                                                 } else {
1257                                                         unsigned short resource_status = current_using_resource & mm_resource;
1258
1259                                                         /* Check conflict with paused instance */
1260                                                         if (resource_status != ASM_RESOURCE_NONE) {
1261                                                                 asm_warning("[ASM_Server] there is system resource conflict with paused instance 0x%x\n",resource_status);
1262                                                                 __print_resource(resource_status);
1263                                                         } else {
1264                                                                 asm_info("[ASM_Server] no resource conflict with paused instance\n");
1265                                                                 break;
1266                                                         }
1267
1268                                                         /* Execute callback function for monitor handle */
1269                                                         int monitor_handle = -1;
1270                                                         if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
1271                                                                 cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
1272                                                                 if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
1273                                                                         asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
1274                                                                 }
1275                                                                 asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
1276
1277                                                                 __set_monitor_dirty(current_play_instance_id);
1278                                                         }
1279
1280                                                         /* Execute callback function for worker handle */
1281                                                         cb_res = __do_callback(current_play_instance_id,current_play_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
1282                                                         if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
1283                                                                 asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
1284                                                         }
1285                                                         asm_warning("[ASM_Server]  __asm_compare_priority_matrix(1STOP_2PLAY) cause RESOURCE : __do_callback Complete : TID=%ld, handle=%d",current_play_instance_id,current_play_handle );
1286
1287                                                         __asm_change_state_list(current_play_instance_id, current_play_handle, ASM_STATE_NONE, ASM_RESOURCE_NONE);
1288                                                 }
1289
1290                                                 asm_info("[ASM_Server] >>>> __asm_compare_priority_matrix(1STOP_2PLAY) cause RESOURCE : msg sent and  then received msg !!!\n");
1291                                                 break;
1292                                         }
1293
1294                                         default:
1295                                         {
1296                                                 /* asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix : ASM_CASE_NONE [do not anything] !!!\n"); */
1297                                                 break;
1298                                         }
1299                                         } /* switch (sound_case) */
1300                                 } else {
1301                                         /* asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix : ASM_CASE_NONE [do not anything] !!!\n"); */
1302                                 }
1303                         } /* if (temp_list->sound_state == ASM_STATE_PAUSE) */
1304
1305                         temp_list = temp_list->next;
1306                 } /* while (temp_list->next != tail_list) */
1307         }
1308
1309         /* Finally, no conflict */
1310         if (no_conflict_flag) {
1311                 if (request_id == ASM_REQUEST_REGISTER) {
1312                         __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
1313                 } else {
1314                         __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
1315                 }
1316         }
1317
1318         /* Send response to client */
1319         asm_snd_msg.instance_id = instance_id;
1320         __asm_snd_message();
1321 }
1322
1323 void __asm_do_all_resume_callback(ASM_event_sources_t eventsrc)
1324 {
1325         asm_instance_list_t *temp_list = head_list;
1326         int cb_res = 0;
1327         int avsys_err = 0;
1328         avsys_audio_playing_devcie_t dev = AVSYS_AUDIO_ROUTE_DEVICE_UNKNOWN;
1329
1330         asm_info("[ASM_Server] __asm_do_all_resume_callback\n");
1331
1332         if (AVSYS_FAIL(avsys_err = avsys_audio_get_playing_device_info(&dev))) {
1333                 asm_error("[ASM_Server] Can not get playing device info\n");
1334         }
1335
1336         while (temp_list->next != tail_list) {
1337                 if (temp_list->need_resume == ASM_NEED_RESUME) {
1338                         if ((avsys_err != AVSYS_STATE_SUCCESS) ||
1339                                         (dev == AVSYS_AUDIO_ROUTE_DEVICE_HANDSET && temp_list->device_when_interrupted != AVSYS_AUDIO_ROUTE_DEVICE_HANDSET)) {
1340                                 asm_warning("[ASM_Server] Skip send resume callback. Because sound path has changed to loud during interruption.\n");
1341                         } else {
1342                                 cb_res = __do_callback(temp_list->instance_id, temp_list->sound_handle, ASM_COMMAND_RESUME, eventsrc);
1343                                 switch (cb_res) {
1344                                 case ASM_CB_RES_PLAYING:
1345                                         temp_list->sound_state = ASM_STATE_PLAYING;
1346                                         break;
1347                                 case ASM_CB_RES_IGNORE:
1348                                 case ASM_CB_RES_NONE:
1349                                 case ASM_CB_RES_STOP:
1350                                 case ASM_CB_RES_PAUSE:
1351                                 default:
1352                                         /* do nothing */
1353                                         break;
1354                                 }
1355                         }
1356                         temp_list->need_resume = ASM_NEED_NOT_RESUME;
1357                 }
1358                 temp_list = temp_list->next;
1359         }
1360 }
1361
1362 #ifdef USE_SECURITY
1363 gboolean __asm_check_check_privilege (unsigned char* cookie)
1364 {
1365         int asm_gid = -1;
1366         int retval = 0;
1367
1368         /* Get ASM server group id */
1369         asm_gid = security_server_get_gid("asm");
1370         asm_info ("[Security] asm server gid = [%d]\n", asm_gid);
1371         if (asm_gid < 0) {
1372                 asm_error ("[Security] security_server_get_gid() failed. error=[%d]\n", asm_gid);
1373                 return false;
1374         }
1375
1376         /* Check privilege with valid group id */
1377         retval = security_server_check_privilege((char *)cookie, asm_gid);
1378         if (retval == SECURITY_SERVER_API_SUCCESS) {
1379                 asm_info("[Security] security_server_check_privilege() returns [%d]\n", retval);
1380                 return true;
1381         } else {
1382                 asm_error("[Security] security_server_check_privilege() returns [%d]\n", retval);
1383                 return false;
1384         }
1385 }
1386 #endif /* USE_SECURITY */
1387
1388 int main()
1389 {
1390         int pid = 0, ret = 0;
1391
1392         if (sysconf_set_mempolicy(OOM_IGNORE)) {
1393                 fprintf(stderr, "set mem policy failed\n");
1394         }
1395         signal(SIGPIPE, SIG_IGN);
1396 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
1397         while (1) {
1398                 if (( pid = fork()) < 0) {
1399                         asm_critical_r("[ASM_Server]Fork Failed!!!\n");
1400                         return 0;
1401                 } else if (pid == 0) {
1402                         break;
1403                 } else if (pid > 0) {
1404                         wait(&ret);
1405                         asm_critical_r("[ASM_Server]worker(child) dead!!!, try to refork()");
1406                 }
1407         }
1408 #endif
1409         __asm_create_message_queue();
1410
1411         int temp_msgctl_id1 = msgctl(asm_snd_msgid, IPC_RMID, 0);
1412         int temp_msgctl_id2 = msgctl(asm_rcv_msgid, IPC_RMID, 0);
1413         int temp_msgctl_id3 = msgctl(asm_cb_msgid, IPC_RMID, 0);
1414
1415
1416         if (temp_msgctl_id1 == -1 || temp_msgctl_id2 == -1 || temp_msgctl_id3 == -1) {
1417                 asm_info("[ASM_Server] msgctl failed with error: \n");
1418                 exit(EXIT_FAILURE);
1419         }
1420         //-------------------------------------------------------------------
1421         /*
1422                 This is unnessasry finaly, but nessasary during implement.
1423         */
1424
1425         __asm_create_message_queue();
1426
1427         head_list = (asm_instance_list_t *)malloc(sizeof(asm_instance_list_t));
1428         tail_list = (asm_instance_list_t *)malloc(sizeof(asm_instance_list_t));
1429         head_list->next = tail_list;
1430         tail_list->next = tail_list;
1431
1432
1433         long int rcv_instance_id;
1434         ASM_requests_t rcv_request_id;
1435         ASM_sound_events_t rcv_sound_event;
1436         ASM_sound_states_t rcv_sound_state;
1437         ASM_resource_t rcv_resource;
1438         int rcv_sound_handle;
1439
1440         /*
1441          * Init Vconf
1442          */
1443         if (vconf_set_int(SOUND_STATUS_KEY, 0)) {
1444                 asm_critical("[ASM_Server] vconf_set_int fail\n");
1445                 if (vconf_set_int(SOUND_STATUS_KEY, 0)) {
1446                         asm_critical_r("[ASM_Server] vconf_set_int fail\n");
1447                 }
1448         }
1449         if (vconf_set_int(HIBERNATION_CHECK_KEY, HIBERNATION_READY)) {
1450                 asm_critical("[ASM_Server] Hibernation check vconf_set_int fail\n");
1451         }
1452
1453 #ifdef SUPPORT_GCF
1454         if (vconf_get_int(VCONFKEY_ADMIN_GCF_TEST, &is_gcf)) {
1455                 asm_warning_r("[ASM_Server] vconf_get_int for VCONFKEY_ADMIN_GCF_TEST failed, set as default\n");
1456                 is_gcf = GCF_DEFAULT;
1457         }
1458 #endif
1459
1460         while (true) {
1461                 asm_info("[ASM_Server] asm_Server is waiting message(%d)!!!\n", asm_is_send_msg_to_cb);
1462
1463                 if (!asm_is_send_msg_to_cb) {
1464                         __asm_rcv_message();
1465
1466                         rcv_instance_id = asm_rcv_msg.instance_id;
1467                         rcv_sound_handle = asm_rcv_msg.data.handle;
1468                         rcv_request_id = asm_rcv_msg.data.request_id;
1469                         rcv_sound_event = asm_rcv_msg.data.sound_event;
1470                         rcv_sound_state = asm_rcv_msg.data.sound_state;
1471                         rcv_resource = asm_rcv_msg.data.system_resource;
1472
1473                         /*******************************************************************/
1474                         asm_info("[ASM_Server] received msg (tid=%ld,handle=%d,req=%d,event=0x%x,state=0x%x,resource=0x%x)\n",
1475                                         rcv_instance_id, rcv_sound_handle, rcv_request_id, rcv_sound_event, rcv_sound_state, rcv_resource);
1476                         if (rcv_request_id != ASM_REQUEST_EMERGENT_EXIT) {
1477                                 asm_warning("[ASM_Server]     request_id : %s\n", ASM_sound_request_str[rcv_request_id]);
1478                                 asm_warning("[ASM_Server]     sound_event : %s\n", ASM_sound_events_str[rcv_sound_event]);
1479                                 asm_warning("[ASM_Server]     sound_state : %s\n", ASM_sound_state_str[rcv_sound_state]);
1480                                 asm_warning("[ASM_Server]     resource : 0x%x\n", rcv_resource);
1481                         }
1482                         /*******************************************************************/
1483
1484                         switch (rcv_request_id) {
1485                         case ASM_REQUEST_REGISTER:
1486 #ifdef USE_SECURITY
1487                                 /* do security check */
1488                                 if (__asm_check_check_privilege(asm_rcv_msg.data.cookie) == 0) {
1489                                         asm_error ("[Security] __asm_check_check_privilege() failed....\n");
1490                                         asm_snd_msg.instance_id = rcv_instance_id;
1491                                         asm_snd_msg.data.alloc_handle = -1;
1492                                         asm_snd_msg.data.cmd_handle = -1;
1493                                         asm_snd_msg.data.check_privilege = 0;
1494                                         __asm_snd_message();
1495                                         break;
1496                                 }
1497                                 asm_info ("[Security] __asm_check_check_privilege() success\n");
1498                                 asm_snd_msg.data.check_privilege = 1;
1499 #endif /* USE_SECURITY */
1500                                 __check_dead_process();
1501
1502                                 __asm_get_empty_handle(rcv_instance_id, &rcv_sound_handle);
1503                                 if (rcv_sound_handle == -1) {
1504                                         asm_snd_msg.instance_id = rcv_instance_id;
1505                                         asm_snd_msg.data.alloc_handle = -1;
1506                                         asm_snd_msg.data.cmd_handle = -1;
1507                                         __asm_snd_message();
1508                                 } else {
1509                                         __asm_compare_priority_matrix(rcv_instance_id, rcv_sound_handle, rcv_request_id, rcv_sound_event, rcv_sound_state, rcv_resource);
1510                                 }
1511
1512                                 break;
1513
1514                         case ASM_REQUEST_UNREGISTER:
1515                                 __asm_unregister_list(rcv_sound_handle);
1516                                 /* only support resuming at end of call & alarm interrupt */
1517                                 switch (rcv_sound_event) {
1518                                 case ASM_EVENT_CALL:
1519                                 case ASM_EVENT_VIDEOCALL:
1520                                         __asm_do_all_resume_callback(ASM_EVENT_SOURCE_CALL_END);
1521                                         break;
1522                                 case ASM_EVENT_ALARM:
1523                                         __asm_do_all_resume_callback(ASM_EVENT_SOURCE_ALARM_END);
1524                                         break;
1525                                 default:
1526                                         break;
1527                                 }
1528
1529                                 break;
1530
1531                         case ASM_REQUEST_SETSTATE:
1532                                 __check_dead_process();
1533                                 if ( rcv_sound_state == ASM_STATE_PLAYING )     {
1534                                         if ( __isItPlayingNow(rcv_instance_id, rcv_sound_handle)) {
1535                                                 __asm_change_state_list(rcv_instance_id, rcv_sound_handle, rcv_sound_state, rcv_resource);
1536
1537                                                 asm_snd_msg.data.cmd_handle = rcv_sound_handle;
1538                                                 asm_snd_msg.data.result_sound_command = ASM_COMMAND_NONE;
1539                                                 asm_snd_msg.data.result_sound_state = rcv_sound_state;
1540                                                 asm_snd_msg.instance_id = rcv_instance_id;
1541
1542                                                 __asm_snd_message();
1543                                         } else {
1544                                                 __asm_compare_priority_matrix(rcv_instance_id, rcv_sound_handle, rcv_request_id, rcv_sound_event, rcv_sound_state, rcv_resource);
1545                                         }
1546                                         __temp_print_list("Set State (Play)");
1547                                 } else {
1548                                         __asm_change_state_list(rcv_instance_id, rcv_sound_handle, rcv_sound_state, rcv_resource);
1549                                         __temp_print_list("Set State (Not Play)");
1550                                 }
1551                                 break;
1552
1553                         case ASM_REQUEST_GETSTATE:
1554                                 asm_snd_msg.instance_id = rcv_instance_id;
1555                                 asm_snd_msg.data.result_sound_state = __asm_find_list(rcv_request_id, rcv_sound_handle);
1556                                 __asm_snd_message();
1557                                 break;
1558
1559                         case ASM_REQUEST_GETMYSTATE:
1560                                 __check_dead_process();
1561                                 asm_snd_msg.instance_id = rcv_instance_id;
1562                                 asm_snd_msg.data.result_sound_state = __asm_find_process_status(rcv_instance_id);
1563                                 __asm_snd_message();
1564                                 break;
1565
1566                         case ASM_REQUEST_DUMP:
1567                                 __temp_print_list("DUMP");
1568                                 break;
1569
1570                         case ASM_REQUEST_EMERGENT_EXIT:
1571                                 emergent_exit(rcv_instance_id);
1572                                 break;
1573
1574                         default:
1575                                 break;
1576                         }
1577                 }
1578         }
1579
1580         return 0;
1581 }
1582