Merge "Removed unused result variable from sound_codec_asm_callback" into tizen
[platform/core/multimedia/libmm-sound.git] / server / mm_sound_mgr_session.c
1 /*
2  * libmm-sound
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 <stdlib.h>
23 #include <string.h>
24 #include <pthread.h>
25 #include <sys/shm.h>
26 #include <sys/msg.h>
27 #include <sys/mman.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <stdbool.h>
31 #include <errno.h>
32
33 #include <vconf.h>
34 #include <mm_error.h>
35 #include <mm_debug.h>
36 #include <audio-session-manager.h>
37 #include <avsys-audio.h>
38
39 #include "../include/mm_sound_common.h"
40 #include "../include/mm_sound_utils.h"
41 #include "include/mm_sound_mgr_common.h"
42 #include "include/mm_sound_mgr_session.h"
43 #include "include/mm_sound_mgr_device.h"
44 #include "include/mm_sound_mgr_headset.h"
45 #include "include/mm_sound_mgr_pulse.h"
46 #include "include/mm_sound_mgr_asm.h"
47 #include "include/mm_sound_hal.h"
48
49 #define EARJACK_WITH_MIC        2
50
51 #define MAX_STRING_LEN  256
52
53 #define MM_SOUND_DEVICE_OUT_ANY 0x000FFF00
54 #define MM_SOUND_DEVICE_IN_ANY   0x000000FF
55
56 #define MM_SOUND_DEVICE_OUT_FILTER 0x000000FF
57 #define MM_SOUND_DEVICE_IN_FILTER        0x000FFF00
58
59 pthread_mutex_t g_mutex_session = PTHREAD_MUTEX_INITIALIZER;
60
61 #define LOCK_SESSION()  do { debug_log("(*)LOCKING\n"); /*pthread_mutex_lock(&g_mutex_session);*/ debug_log("(+)LOCKED\n"); }while(0)
62 #define UNLOCK_SESSION()  do {  /* pthread_mutex_unlock(&g_mutex_session);*/ debug_log("(-)UNLOCKED\n"); }while(0)
63
64 #define RESET_ACTIVE(x)    (g_info.device_active &= x)
65 #define RESET_AVAILABLE(x)    (g_info.device_available &= x)
66
67 #define SET_ACTIVE(x)    (g_info.device_active |= x)
68 #define SET_AVAILABLE(x)    (g_info.device_available |= x)
69
70 #define SET_PLAYBACK_ONLY_ACTIVE(x)  do { RESET_ACTIVE(MM_SOUND_DEVICE_OUT_FILTER); SET_ACTIVE(x); }while(0)
71 #define SET_CAPTURE_ONLY_ACTIVE(x)  do {  RESET_ACTIVE(MM_SOUND_DEVICE_IN_FILTER); SET_ACTIVE(x); }while(0)
72
73
74 #define UNSET_ACTIVE(x)    (g_info.device_active &= (~x))
75 #define UNSET_AVAILABLE(x)    (g_info.device_available &= (~x))
76
77 #define TOGGLE_ACTIVE(x)    (g_info.device_active ^= x)
78 #define TOGGLE_AVAILABLE(x)    (g_info.device_available ^= x)
79
80 #define IS_ACTIVE(x)    (g_info.device_active & x)
81 #define IS_AVAILABLE(x)    (g_info.device_available & x)
82
83 #define GET_AVAILABLE_PLAYBACK()        IS_AVAILABLE(MM_SOUND_DEVICE_OUT_ANY)
84 #define GET_AVAILABLE_CAPTURE() IS_AVAILABLE(MM_SOUND_DEVICE_IN_ANY)
85
86 #define GET_ACTIVE_PLAYBACK()   IS_ACTIVE(MM_SOUND_DEVICE_OUT_ANY)
87 #define GET_ACTIVE_CAPTURE()    IS_ACTIVE(MM_SOUND_DEVICE_IN_ANY)
88
89 #define IS_COMMUNICATION_SESSION() ((g_info.session == SESSION_VOICECALL) || (g_info.session == SESSION_VOIP))
90 #define IS_NOTIFICATION_SESSION() (g_info.session == SESSION_NOTIFICATION)
91 #define IS_EMERGENCY_SESSION() (g_info.session == SESSION_EMERGENCY)
92
93 static int __set_sound_path_for_current_active ();
94 static int __set_sound_path_to_dual ();
95 static int __set_sound_path_to_speaker ();
96 static void __select_playback_active_device (void);
97 static void __select_capture_active_device (void);
98
99 #define ENABLE_CALLBACK
100 #ifndef ENABLE_CALLBACK
101 #define _mm_sound_mgr_device_available_device_callback(a,b,c)   MM_ERROR_NONE
102 #define _mm_sound_mgr_device_active_device_callback(a,b)        MM_ERROR_NONE
103 #endif
104
105 typedef struct _session_info_struct
106 {
107         int asm_handle;
108         int device_available;
109         int device_active;
110         int headset_type;
111
112         session_t session;
113         subsession_t subsession;
114
115         char bt_name[MAX_STRING_LEN];
116         char default_sink_name[MAX_STRING_LEN];
117
118
119 } SESSION_INFO_STRUCT;
120
121
122 SESSION_INFO_STRUCT g_info;
123
124 typedef enum
125 {
126         NO_NOTI = 0,
127         DO_NOTI
128 } noti_t;
129
130
131 static void dump_info ()
132 {
133         int i = 0;
134
135         const char *playback_device_str[] = { "SPEAKER ", "RECEIVER ", "HEADSET ", "BTSCO ", "BTA2DP ", "DOCK ", "HDMI ", "WFD ", "USB " };
136         const char *capture_device_str[] = { "MAINMIC ", "HEADSET ", "BTMIC "  };
137
138         int playback_max = sizeof (playback_device_str) / sizeof (char*);
139         int capture_max = sizeof (capture_device_str) / sizeof (char*);
140
141         static char tmp_str[128];
142         static char tmp_str2[128];
143
144         debug_log ("<----------------------------------------------------->\n");
145
146
147         strcpy (tmp_str, "PLAYBACK = [ ");
148         for (i=0; i<playback_max; i++) {
149                 if (((g_info.device_available & MM_SOUND_DEVICE_OUT_ANY) >> 8) & (0x01 << i)) {
150                         strcat (tmp_str, playback_device_str[i]);
151                 }
152         }
153         strcat (tmp_str, "]");
154
155         strcpy (tmp_str2, "CAPTURE = [ ");
156                 for (i=0; i<capture_max; i++) {
157                         if ((g_info.device_available & MM_SOUND_DEVICE_IN_ANY) & (0x01 << i)) {
158                                 strcat (tmp_str2, capture_device_str[i]);
159                         }
160         }
161         strcat (tmp_str2, "]");
162         debug_log ("*** Available = [0x%08x], %s %s", g_info.device_available, tmp_str, tmp_str2);
163
164         strcpy (tmp_str, "PLAYBACK = [ ");
165         for (i=0; i<playback_max; i++) {
166                 if (((g_info.device_active & MM_SOUND_DEVICE_OUT_ANY) >> 8) & (0x01 << i)) {
167                         strcat (tmp_str, playback_device_str[i]);
168                 }
169         }
170         strcat (tmp_str, "]");
171
172         strcpy (tmp_str2, "CAPTURE = [ ");
173                 for (i=0; i<capture_max; i++) {
174                         if ((g_info.device_active & MM_SOUND_DEVICE_IN_ANY) & (0x01 << i)) {
175                                 strcat (tmp_str2, capture_device_str[i]);
176                         }
177         }
178         strcat (tmp_str2, "]");
179         debug_log ("***    Active = [0x%08x], %s %s", g_info.device_active, tmp_str, tmp_str2);
180
181
182         debug_log ("*** Headset type = [%d], BT = [%s], default sink = [%s]\n", g_info.headset_type, g_info.bt_name, g_info.default_sink_name);
183         debug_log ("*** Session = [%d], SubSession = [%d]\n", g_info.session, g_info.subsession);
184         debug_log ("<----------------------------------------------------->\n");
185 }
186
187 /* ------------------------- ASM ------------------------------------*/
188 static pthread_mutex_t _asm_mutex = PTHREAD_MUTEX_INITIALIZER;
189
190 #ifndef MURPHY
191 static bool _asm_register_for_headset (int * handle)
192 {
193         int asm_error = 0;
194
195         if (handle == NULL) {
196                 debug_error ("Handle is not valid!!!\n");
197                 return false;
198         }
199
200         if (!ASM_register_sound_ex (-1, handle, ASM_EVENT_EARJACK_UNPLUG, ASM_STATE_NONE, NULL, NULL, ASM_RESOURCE_NONE, &asm_error, __asm_process_message)) {
201                         debug_warning("earjack event register failed with 0x%x\n", asm_error);
202                         return false;
203         }
204
205         return true;
206 }
207
208 static void _asm_pause_process(int handle)
209 {
210         int asm_error = 0;
211
212         MMSOUND_ENTER_CRITICAL_SECTION( &_asm_mutex )
213
214         /* If no asm handle register here */
215         if (g_info.asm_handle ==  -1) {
216                 debug_msg ("ASM handle is not valid, try to register once more\n");
217
218                 /* This register should be success */
219                 if (_asm_register_for_headset (&g_info.asm_handle)) {
220                         debug_msg("_asm_register_for_headset() success\n");
221                 } else {
222                         debug_error("_asm_register_for_headset() failed\n");
223                 }
224         }
225
226         //do pause
227         debug_warning("Send earphone unplug event to Audio Session Manager Server for BT headset\n");
228
229         if (!ASM_set_sound_state_ex(handle, ASM_EVENT_EARJACK_UNPLUG, ASM_STATE_PLAYING, ASM_RESOURCE_NONE, &asm_error, __asm_process_message)) {
230                 debug_error("earjack event set sound state to playing failed with 0x%x\n", asm_error);
231         }
232
233         if (!ASM_set_sound_state_ex(handle, ASM_EVENT_EARJACK_UNPLUG, ASM_STATE_STOP, ASM_RESOURCE_NONE, &asm_error, __asm_process_message)) {
234                 debug_error("earjack event set sound state to stop failed with 0x%x\n", asm_error);
235         }
236
237         MMSOUND_LEAVE_CRITICAL_SECTION( &_asm_mutex )
238 }
239
240 static bool _asm_unregister_for_headset (int *handle)
241 {
242         int asm_error = 0;
243
244         if (handle == NULL) {
245                 debug_error ("Handle is not valid!!!\n");
246                 return false;
247         }
248
249         if (!ASM_unregister_sound_ex(*handle, ASM_EVENT_EARJACK_UNPLUG, &asm_error, __asm_process_message)) {
250                 debug_error("earjack event unregister failed with 0x%x\n", asm_error);
251                 return false;
252         }
253
254         return true;
255 }
256 #endif
257
258 /* ------------------------- INTERNAL FUNCTIONS ------------------------------------*/
259
260 static void __set_path_with_notification(noti_t noti)
261 {
262         int ret = MM_ERROR_NONE;
263
264         debug_msg ("[%s] noti=%d\n", __func__,noti);
265
266         /* Set path based on current active device */
267         ret = __set_sound_path_for_current_active();
268         if (ret != MM_ERROR_NONE) {
269                 debug_error ("__set_sound_path_for_current_active() failed [%x]\n", ret);
270                 return;
271         }
272
273         if (noti == DO_NOTI) {
274                 /* Notify current active device */
275                 ret = _mm_sound_mgr_device_active_device_callback(GET_ACTIVE_CAPTURE(), GET_ACTIVE_PLAYBACK());
276                 if (ret != MM_ERROR_NONE) {
277                         debug_error ("_mm_sound_mgr_device_active_device_callback() failed [%x]\n", ret);
278                 }
279         }
280 }
281
282 static int __set_playback_route_communication (session_state_t state)
283 {
284         int ret = MM_ERROR_NONE;
285         int gain;
286
287         debug_fenter();
288
289         if (state == SESSION_START) {
290                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_RECEIVER);
291                 debug_log ("voicecall session started...only receiver available set on...");
292
293                 ret = _mm_sound_mgr_device_available_device_callback(MM_SOUND_DEVICE_IN_NONE, MM_SOUND_DEVICE_OUT_RECEIVER, 1);
294                 if (ret != MM_ERROR_NONE) {
295                         debug_error ("_mm_sound_mgr_device_available_device_callback() failed [%x]\n", ret);
296                         goto ROUTE_COMM_EXIT;
297                 }
298
299                 /* Set default subsession as MEDIA */
300                 g_info.subsession = SUBSESSION_MEDIA;
301
302                 /* (speaker = receiver, headset = headset, bt a2dp = bt sco) */
303                 /* OUT */
304                 if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_SPEAKER)) {
305                         debug_log ("active out was SPEAKER => activate receiver!!\n");
306                         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_RECEIVER);
307
308                 } else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_BT_A2DP)) {
309                         debug_log ("active out was BT A2DP => activate BT SCO!!\n");
310                         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_BT_SCO);
311                         SET_CAPTURE_ONLY_ACTIVE(MM_SOUND_DEVICE_IN_BT_SCO);
312                 }
313                 /* FIXME : Do we have to set IN device ??? */
314
315                 __set_path_with_notification(DO_NOTI);
316
317                 dump_info();
318
319         } else { /* SESSION_END */
320                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_RECEIVER);
321
322                 ret = _mm_sound_mgr_device_available_device_callback(MM_SOUND_DEVICE_IN_NONE, MM_SOUND_DEVICE_OUT_RECEIVER, 0);
323                 if (ret != MM_ERROR_NONE) {
324                         debug_error ("_mm_sound_mgr_device_available_device_callback() failed [%x]\n", ret);
325                         goto ROUTE_COMM_EXIT;
326                 }
327
328                 // RESET
329                 if (g_info.session == SESSION_VOICECALL)
330                         gain = AVSYS_AUDIO_GAIN_EX_VOICECALL;
331                 else if (g_info.session == SESSION_VOIP)
332                         gain = AVSYS_AUDIO_GAIN_EX_VIDEOCALL;
333                 else {
334                         debug_warning ("Not valid session info....[%d]\n", g_info.session);
335                         gain = AVSYS_AUDIO_GAIN_EX_VOICECALL;
336                 }
337
338
339                 if (audio_hal_set_sound_path(gain,
340                                 AVSYS_AUDIO_PATH_EX_NONE, AVSYS_AUDIO_PATH_EX_NONE,
341                                 AVSYS_AUDIO_PATH_OPTION_NONE)) {
342                         debug_error ("audio_hal_set_sound_path() failed\n");
343                         ret = MM_ERROR_SOUND_INTERNAL;
344                         goto ROUTE_COMM_EXIT;
345                 }
346
347                 /* activate current available device based on priority */
348                 debug_log ("Reset ACTIVE and find new one by priority.\n");
349                 RESET_ACTIVE(0);
350                 __select_playback_active_device();
351                 __select_capture_active_device();
352
353                 debug_log ("voicecall session stopped...set path based on current active device");
354                 __set_path_with_notification(DO_NOTI);
355
356                 dump_info();
357         }
358
359 ROUTE_COMM_EXIT:
360
361         debug_fleave();
362
363         return ret;
364 }
365
366 static int __set_playback_route_fmradio (session_state_t state)
367 {
368         int ret = MM_ERROR_NONE;
369         int out = 0; // initizlize out
370
371         debug_fenter();
372
373         if (state == SESSION_START) {
374
375                 if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_SPEAKER))
376                         out = AVSYS_AUDIO_PATH_EX_SPK;
377                 else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY))
378                         out = AVSYS_AUDIO_PATH_EX_HEADSET;
379                 else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_BT_A2DP))
380                         out = AVSYS_AUDIO_PATH_EX_A2DP;
381
382                 /* PATH SET */
383                 if (audio_hal_set_sound_path(AVSYS_AUDIO_GAIN_EX_FMRADIO,
384                                                                                 out, AVSYS_AUDIO_PATH_EX_FMINPUT,
385                                                                                 AVSYS_AUDIO_PATH_OPTION_NONE))  {
386                         debug_error ("audio_hal_set_sound_path() failed\n");
387                         ret = MM_ERROR_SOUND_INTERNAL;
388                         goto ROUTE_FMRADIO_EXIT;
389                 }
390
391         } else { /* SESSION_END */
392                 /* PATH RELEASE */
393                 if (audio_hal_set_sound_path(AVSYS_AUDIO_GAIN_EX_FMRADIO,
394                                                                                 AVSYS_AUDIO_PATH_EX_NONE, AVSYS_AUDIO_PATH_EX_NONE,
395                                                                                 AVSYS_AUDIO_PATH_OPTION_NONE)) {
396                         debug_error ("audio_hal_set_sound_path() failed\n");
397                         ret = MM_ERROR_SOUND_INTERNAL;
398                         goto ROUTE_FMRADIO_EXIT;
399                 }
400
401                 /* Set as current active status */
402                 __set_path_with_notification (NO_NOTI);
403         }
404
405         if (AVSYS_FAIL(avsys_audio_set_ext_device_status(AVSYS_AUDIO_EXT_DEVICE_FMRADIO, state))) {
406                 debug_error ("avsys_audio_set_ext_device_status() failed\n");
407                 ret = MM_ERROR_SOUND_INTERNAL;
408         }
409
410 ROUTE_FMRADIO_EXIT:
411
412         debug_fleave();
413
414         return ret;
415 }
416
417 static int __set_playback_route_notification (session_state_t state)
418 {
419         int ret = MM_ERROR_NONE;
420
421         debug_fenter();
422
423         if (state == SESSION_START) {
424                 ret = __set_sound_path_to_dual ();
425                 if (ret != MM_ERROR_NONE) {
426                         debug_error ("__set_sound_path_to_dual() failed [%x]\n", ret);
427                 }
428
429         } else { /* SESSION_END */
430                 __set_path_with_notification (NO_NOTI);
431         }
432
433         debug_fleave();
434
435         return ret;
436 }
437
438 static int __set_playback_route_emergency (session_state_t state)
439 {
440         int ret = MM_ERROR_NONE;
441
442         debug_fenter();
443
444         if (state == SESSION_START) {
445                 ret = __set_sound_path_to_speaker ();
446                 if (ret != MM_ERROR_NONE) {
447                         debug_error ("__set_sound_path_to_speaker() failed [%x]\n", ret);
448                 }
449
450         } else { /* SESSION_END */
451                 __set_path_with_notification (NO_NOTI);
452         }
453
454         debug_fleave();
455
456         return ret;
457 }
458
459 static bool __is_forced_session ()
460 {
461         return (IS_NOTIFICATION_SESSION() || IS_EMERGENCY_SESSION())? true : false;
462 }
463
464 static int __set_sound_path_for_current_active (void)
465 {
466         int ret = MM_ERROR_NONE;
467         int option = AVSYS_AUDIO_PATH_OPTION_NONE;
468         int in = 0, out = 0, gain = 0;
469         int sound_play;
470
471         debug_fenter();
472
473         if (__is_forced_session()) {
474                 debug_log ("Current session is NOTI/EMER, pending path setting. path set will be done after session ends")
475                 goto CURRENT_ACTIVE_END;
476         }
477
478         /* Pulseaudio route */
479         if (audio_hal_pulse_sink_route(g_info.device_active)) {
480                 goto CURRENT_ACTIVE_END;
481         }
482         if (audio_hal_pulse_source_route(g_info.device_active)) {
483                 goto CURRENT_ACTIVE_END;
484         }
485
486         /* prepare IN */
487         if (IS_ACTIVE(MM_SOUND_DEVICE_IN_MIC)) {
488                 in = AVSYS_AUDIO_PATH_EX_MIC;
489         } else if (IS_ACTIVE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY)) {
490                 in = AVSYS_AUDIO_PATH_EX_HEADSETMIC;
491         } else if (IS_ACTIVE(MM_SOUND_DEVICE_IN_BT_SCO)) {
492                 in = AVSYS_AUDIO_PATH_EX_BTMIC;
493         }
494
495         /* prepare OUT */
496         if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_SPEAKER)) {
497                 out = AVSYS_AUDIO_PATH_EX_SPK;
498         } else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_RECEIVER)) {
499                 out = AVSYS_AUDIO_PATH_EX_RECV;
500         } else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY)) {
501                 out = AVSYS_AUDIO_PATH_EX_HEADSET;
502         } else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_BT_SCO)) {
503                 out = AVSYS_AUDIO_PATH_EX_BTHEADSET;
504         } else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_DOCK)) {
505                 out = AVSYS_AUDIO_PATH_EX_DOCK;
506         } else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_HDMI)) {
507                 out = AVSYS_AUDIO_PATH_EX_HDMI;
508         } else if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_WFD)) {
509 #ifndef USE_PULSE_WFD
510                 out = AVSYS_AUDIO_PATH_EX_HDMI;
511 #endif
512         }
513
514         /* prepare GAIN */
515         switch (g_info.session) {
516         case SESSION_MEDIA:
517         case SESSION_NOTIFICATION:
518         case SESSION_EMERGENCY:
519                 gain = AVSYS_AUDIO_GAIN_EX_KEYTONE;
520                 break;
521
522         case SESSION_VOICECALL:
523         case SESSION_VOIP:
524                 if (g_info.subsession == SUBSESSION_RINGTONE) {
525                         gain = AVSYS_AUDIO_GAIN_EX_RINGTONE;
526                         in = AVSYS_AUDIO_PATH_EX_NONE;
527
528                         /* If sound is mute mode, force ringtone path to headset */
529                         vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_play);
530                         if (sound_play) {
531                                 /* Normal Ringtone */
532                                 out = AVSYS_AUDIO_PATH_EX_SPK;
533                                 option = AVSYS_AUDIO_PATH_OPTION_DUAL_OUT;
534                         } else {
535                                 /* Mute Ringtone */
536                                 out = AVSYS_AUDIO_PATH_EX_HEADSET;
537                         }
538                 } else if (g_info.subsession == SUBSESSION_MEDIA) {
539                         gain = AVSYS_AUDIO_GAIN_EX_CALLTONE;
540                         in = AVSYS_AUDIO_PATH_EX_NONE;
541                 } else if (g_info.subsession == SUBSESSION_VOICE) {
542                         gain = (g_info.session == SESSION_VOICECALL)?
543                                         AVSYS_AUDIO_GAIN_EX_VOICECALL : AVSYS_AUDIO_GAIN_EX_VIDEOCALL;
544
545                         if (out == AVSYS_AUDIO_PATH_EX_HEADSET) {
546                                 debug_log ("Fix in path to headsetmic when out path is headset\n");
547                                 in = AVSYS_AUDIO_PATH_EX_HEADSETMIC;
548                         }
549                 } else {
550                         debug_warning ("Unexpected SUBSESSION [%d]\n", g_info.subsession);
551                 }
552                 break;
553
554         case SESSION_FMRADIO:
555                 gain = AVSYS_AUDIO_GAIN_EX_FMRADIO;
556                 in = AVSYS_AUDIO_PATH_EX_FMINPUT;
557                 break;
558
559         default:
560                 debug_warning ("session [%d] is not handled...\n", g_info.session);
561                 break;
562         }
563
564         /* Set Path (GAIN, OUT, IN) */
565         if (audio_hal_set_sound_path(gain, out, in, option)) {
566                 debug_error ("audio_hal_set_sound_path failed\n");
567                 ret = MM_ERROR_SOUND_INTERNAL;
568         }
569
570 CURRENT_ACTIVE_END:
571         /* clean up */
572         debug_fleave();
573         return ret;
574 }
575
576 static int __set_sound_path_to_dual (void)
577 {
578         int ret = MM_ERROR_NONE;
579
580         debug_fenter();
581
582         /* Sound path for ALSA */
583         debug_log ("Set path to DUAL.\n");
584         if (audio_hal_set_sound_path(AVSYS_AUDIO_GAIN_EX_KEYTONE,
585                                                 AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_NONE,
586                                                 AVSYS_AUDIO_PATH_OPTION_DUAL_OUT)) {
587                 debug_error ("audio_hal_set_sound_path() failed\n");
588                 ret = MM_ERROR_SOUND_INTERNAL;
589         }
590
591         /* clean up */
592         debug_fleave();
593         return ret;
594 }
595
596 static int __set_sound_path_to_speaker (void)
597 {
598         int ret = MM_ERROR_NONE;
599
600         debug_fenter();
601
602         /* Sound path for ALSA */
603         debug_log ("Set path to SPEAKER.\n");
604         if (audio_hal_set_sound_path(AVSYS_AUDIO_GAIN_EX_KEYTONE,
605                                                 AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_NONE,
606                                                 AVSYS_AUDIO_PATH_OPTION_NONE)) {
607                 debug_error ("audio_hal_set_sound_path failed\n");
608                 ret = MM_ERROR_SOUND_INTERNAL;
609         }
610
611         /* clean up */
612         debug_fleave();
613         return ret;
614 }
615
616 static void __select_playback_active_device (void)
617 {
618         if (IS_ACTIVE(MM_SOUND_DEVICE_OUT_ANY)) {
619                 debug_log ("Active device exists. Nothing needed...\n");
620                 return;
621         }
622
623         debug_log ("No playback active device, set active based on priority!!\n");
624
625         /* set active device based on device priority (bt>ear>spk) */
626         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_A2DP)) {
627                 debug_log ("BT A2DP available, set as active!!\n");
628                 SET_ACTIVE(MM_SOUND_DEVICE_OUT_BT_A2DP);
629         } else if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_WFD)) {
630                 debug_log ("WFD available, set as active!!\n");
631                 SET_ACTIVE(MM_SOUND_DEVICE_OUT_WFD);
632         } else if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_DOCK)) {
633                 debug_log ("DOCK available, set as active!!\n");
634                 SET_ACTIVE(MM_SOUND_DEVICE_OUT_DOCK);
635         } else if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_HDMI)) {
636                 debug_log ("HDMI available, set as active!!\n");
637                 SET_ACTIVE(MM_SOUND_DEVICE_OUT_HDMI);
638         } else if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_USB_AUDIO)) {
639                 debug_log ("USB Audio available, set as active!!\n");
640                 SET_ACTIVE(MM_SOUND_DEVICE_OUT_USB_AUDIO);
641         } else if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY)) {
642                 debug_log ("WIRED available, set as active!!\n");
643                 SET_ACTIVE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY);
644         } else {
645                 debug_log ("SPEAKER available, set as active!!\n");
646                 SET_ACTIVE(MM_SOUND_DEVICE_OUT_SPEAKER);
647         }
648 }
649
650 static void __select_capture_active_device (void)
651 {
652         if (IS_ACTIVE(MM_SOUND_DEVICE_IN_ANY)) {
653                 debug_log ("Active device exists. Nothing needed...\n");
654                 return;
655         }
656
657         debug_log ("No capture active device, set active based on priority!!\n");
658
659         /* set active device based on device priority (bt>ear>spk) */
660         if (IS_AVAILABLE(MM_SOUND_DEVICE_IN_BT_SCO) && IS_COMMUNICATION_SESSION()) {
661                 debug_log ("BT SCO available, set as active!!\n");
662                 SET_ACTIVE(MM_SOUND_DEVICE_IN_BT_SCO);
663         } else if (IS_AVAILABLE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY)) {
664                 debug_log ("WIRED available, set as active!!\n");
665                 SET_ACTIVE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY);
666         } else {
667                 debug_log ("MIC available, set as active!!\n");
668                 SET_ACTIVE(MM_SOUND_DEVICE_IN_MIC);
669         }
670 }
671
672 static void __set_initial_active_device (void)
673 {
674         int type = 0;
675         bool a2dp = 0, sco = 0;
676
677         /* Set SPK & MIC as default available device */
678         /* FIXME : spk & mic can be always on??? */
679         SET_AVAILABLE(MM_SOUND_DEVICE_OUT_SPEAKER);
680         SET_AVAILABLE(MM_SOUND_DEVICE_IN_MIC);
681
682         /* Get wired status and set available status */
683         MMSoundMgrHeadsetGetType (&type);
684         if (type > 0) {
685                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY);
686                 if (type == EARJACK_WITH_MIC) {
687                         SET_AVAILABLE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY);
688                 }
689         }
690
691         /* Get BT status and set available status */
692         MMSoundMgrPulseGetInitialBTStatus (&a2dp, &sco);
693         if (a2dp) {
694                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_A2DP);
695         }
696         if (sco) {
697                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_SCO);
698                 SET_AVAILABLE(MM_SOUND_DEVICE_IN_BT_SCO);
699         }
700
701         /* Set Active device based on priority */
702         __select_playback_active_device ();
703         __select_capture_active_device ();
704
705         __set_path_with_notification (NO_NOTI);
706
707         dump_info();
708 }
709
710 static void __handle_bt_a2dp_on (void)
711 {
712         int ret = MM_ERROR_NONE;
713
714         /* at this time, pulseaudio default sink is bt sink */
715         if (IS_COMMUNICATION_SESSION()) {
716                 debug_log ("Current session is VOICECALL, no auto-activation!!!\n");
717                 return;
718         }
719
720         debug_log ("Activate BT_A2DP device\n");
721         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_BT_A2DP);
722
723         ret = _mm_sound_mgr_device_active_device_callback(GET_ACTIVE_CAPTURE(), GET_ACTIVE_PLAYBACK());
724         if (ret != MM_ERROR_NONE) {
725                 debug_error ("_mm_sound_mgr_device_active_device_callback() failed [%x]\n", ret);
726         }
727
728         dump_info ();
729 }
730
731 static void __handle_bt_a2dp_off (void)
732 {
733         if (!IS_ACTIVE(MM_SOUND_DEVICE_OUT_BT_A2DP)) {
734                 debug_msg("MM_SOUND_DEVICE_OUT_BT_A2DP was not active. nothing to do here.");
735                 dump_info ();
736                 return;
737         }
738
739 #ifndef MURPHY
740         /* if bt was active, then do asm pause */
741         debug_msg("Do pause here");
742         _asm_pause_process (g_info.asm_handle);
743 #endif
744
745         /* set bt device to none */
746         debug_msg("Deactivate BT_A2DP device\n");
747         UNSET_ACTIVE(MM_SOUND_DEVICE_OUT_BT_A2DP);
748
749         /* activate current available device based on priority */
750         __select_playback_active_device();
751
752         /* Do set path and notify result */
753         __set_path_with_notification(DO_NOTI);
754
755         dump_info ();
756 }
757
758 static void __handle_bt_sco_off (void)
759 {
760         /* If sco is not activated, just return */
761         if (!IS_ACTIVE(MM_SOUND_DEVICE_OUT_BT_SCO) && !IS_ACTIVE(MM_SOUND_DEVICE_IN_BT_SCO)) {
762                 debug_msg("BT SCO was not active. nothing to do here.");
763                 dump_info ();
764                 return;
765         }
766
767         /* set bt device to none */
768         debug_msg("Deactivate BT_SCO device\n");
769         UNSET_ACTIVE(MM_SOUND_DEVICE_OUT_BT_SCO);
770         UNSET_ACTIVE(MM_SOUND_DEVICE_IN_BT_SCO);
771
772         /* activate current available device based on priority */
773         __select_playback_active_device();
774         __select_capture_active_device();
775
776         /* Do set path and notify result */
777         __set_path_with_notification(DO_NOTI);
778
779         dump_info ();
780 }
781
782 static void __handle_headset_on (int type)
783 {
784         /* at this time, pulseaudio default sink is bt sink */
785         /* if fmradio session, do nothing */
786
787         /* Skip when noti session */
788
789         /* ToDo : alarm/notification session ???? */
790         if (IS_COMMUNICATION_SESSION()) {
791                 debug_log ("Current session is VOICECALL, no auto-activation!!!\n");
792                 return;
793         }
794
795         debug_log ("Activate WIRED OUT device\n");
796         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY);
797         if (type == EARJACK_WITH_MIC) {
798                 debug_log ("Activate WIRED IN device\n");
799                 SET_CAPTURE_ONLY_ACTIVE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY);
800         }
801
802         /* Do set path and notify result */
803         __set_path_with_notification(DO_NOTI);
804
805         dump_info ();
806 }
807
808 static void __handle_headset_off (void)
809 {
810         if (!IS_ACTIVE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY)) {
811                 debug_msg("MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY was not active. nothing to do here.");
812                 return;
813         }
814
815 #ifndef MURPHY
816         /* if bt was active, then do asm pause */
817         debug_msg("Do pause here");
818         _asm_pause_process (g_info.asm_handle);
819 #endif
820
821         /* set bt device to none */
822         debug_msg("Deactivate WIRED IN/OUT device\n");
823         UNSET_ACTIVE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY);
824         UNSET_ACTIVE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY);
825
826         /* For voicecall session, activation device is up-to application policy */
827         if (IS_COMMUNICATION_SESSION()) {
828                 debug_log ("Current session is VOICECALL, no auto-activation!!!\n");
829                 return;
830         }
831
832         /* activate current available device based on priority */
833         __select_playback_active_device();
834         __select_capture_active_device();
835
836         /* Do set path and notify result */
837         __set_path_with_notification(DO_NOTI);
838
839         dump_info ();
840 }
841
842 static void __handle_dock_on (void)
843 {
844         /* ToDo : alarm/notification session ???? */
845         if (IS_COMMUNICATION_SESSION()) {
846                 debug_log ("Current session is VOICECALL, no auto-activation!!!\n");
847                 return;
848         }
849
850         debug_log ("Activate DOCK device\n");
851         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_DOCK);
852
853         /* Do set path and notify result */
854         __set_path_with_notification(DO_NOTI);
855
856         dump_info ();
857 }
858
859 static void __handle_dock_off (void)
860 {
861         if (!IS_ACTIVE(MM_SOUND_DEVICE_OUT_DOCK)) {
862                 debug_msg("MM_SOUND_DEVICE_OUT_DOCK was not active. nothing to do here.");
863                 return;
864         }
865
866         /* No PAUSE on Dock off case */
867
868         /* set DOCK device to none */
869         debug_msg("Deactivate DOCK device\n");
870         UNSET_ACTIVE(MM_SOUND_DEVICE_OUT_DOCK);
871
872         /* activate current available device based on priority */
873         __select_playback_active_device();
874
875         /* Do set path and notify result */
876         __set_path_with_notification(DO_NOTI);
877
878         dump_info ();
879 }
880
881 static void __handle_hdmi_on (void)
882 {
883         /* ToDo : alarm/notification session ???? */
884         if (IS_COMMUNICATION_SESSION()) {
885                 debug_log ("Current session is VOICECALL, no auto-activation!!!\n");
886                 return;
887         }
888
889         debug_log ("Activate HDMI device\n");
890         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_HDMI);
891
892         /* Do set path and notify result */
893         __set_path_with_notification(DO_NOTI);
894
895         dump_info ();
896 }
897
898 static void __handle_hdmi_off (void)
899 {
900         if (!IS_ACTIVE(MM_SOUND_DEVICE_OUT_HDMI)) {
901                 debug_msg("MM_SOUND_DEVICE_OUT_HDMI was not active. nothing to do here.");
902                 return;
903         }
904
905 #ifndef MURPHY
906         /* if HDMI was active, then do asm pause */
907         debug_msg("Do pause here");
908         _asm_pause_process (g_info.asm_handle);
909 #endif
910
911         /* set DOCK device to none */
912         debug_msg("Deactivate HDMIdevice\n");
913         UNSET_ACTIVE(MM_SOUND_DEVICE_OUT_HDMI);
914
915         /* activate current available device based on priority */
916         __select_playback_active_device();
917
918         /* Do set path and notify result */
919         __set_path_with_notification(DO_NOTI);
920
921         dump_info ();
922 }
923
924 static void __handle_wfd_on (void)
925 {
926         /* ToDo : alarm/notification session ???? */
927         if (IS_COMMUNICATION_SESSION()) {
928                 debug_log ("Current session is VOICECALL, no auto-activation!!!\n");
929                 return;
930         }
931
932         debug_log ("Activate WFD device\n");
933         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_WFD);
934
935         /* Do set path and notify result */
936         __set_path_with_notification(DO_NOTI);
937
938         dump_info ();
939 }
940
941 static void __handle_wfd_off (void)
942 {
943         if (!IS_ACTIVE(MM_SOUND_DEVICE_OUT_WFD)) {
944                 debug_msg("MM_SOUND_DEVICE_OUT_WFD was not active. nothing to do here.");
945                 return;
946         }
947
948 #ifndef MURPHY
949         /* if WFD was active, then do asm pause */
950         debug_msg("Do pause here");
951         _asm_pause_process (g_info.asm_handle);
952 #endif
953
954         /* set WFD device to none */
955         debug_msg("Deactivate WFD device\n");
956         UNSET_ACTIVE(MM_SOUND_DEVICE_OUT_WFD);
957
958         /* activate current available device based on priority */
959         __select_playback_active_device();
960
961         /* Do set path and notify result */
962         __set_path_with_notification(DO_NOTI);
963
964         dump_info ();
965 }
966
967 static void __handle_usb_audio_on (void)
968 {
969         int ret = MM_ERROR_NONE;
970
971         if (IS_COMMUNICATION_SESSION()) {
972                 debug_log ("Current session is VOICECALL, no auto-activation!!!\n");
973                 return;
974         }
975
976         debug_log ("Activate USB Audio device\n");
977         SET_PLAYBACK_ONLY_ACTIVE(MM_SOUND_DEVICE_OUT_USB_AUDIO);
978
979         ret = _mm_sound_mgr_device_active_device_callback(GET_ACTIVE_CAPTURE(), GET_ACTIVE_PLAYBACK());
980         if (ret != MM_ERROR_NONE) {
981                 debug_error ("_mm_sound_mgr_device_active_device_callback() failed [%x]\n", ret);
982         }
983
984         dump_info ();
985 }
986
987 static void __handle_usb_audio_off (void)
988 {
989         if (!IS_ACTIVE(MM_SOUND_DEVICE_OUT_USB_AUDIO)) {
990                 debug_msg("MM_SOUND_DEVICE_OUT_USB_AUDIO was not active. nothing to do here.");
991                 dump_info ();
992                 return;
993         }
994
995 #ifndef MURPHY
996         /* if device was active, then do asm pause */
997         debug_msg("Do pause here");
998         _asm_pause_process (g_info.asm_handle);
999 #endif
1000
1001         /* set bt device to none */
1002         debug_msg("Deactivate USB Audio device\n");
1003         UNSET_ACTIVE(MM_SOUND_DEVICE_OUT_USB_AUDIO);
1004
1005         /* activate current available device based on priority */
1006         __select_playback_active_device();
1007
1008         /* Do set path and notify result */
1009         __set_path_with_notification(DO_NOTI);
1010
1011         dump_info ();
1012 }
1013
1014
1015 /* ------------------------- EXTERNAL FUNCTIONS ------------------------------------*/
1016 /* DEVICE : Called by mgr_pulse for updating current default_sink_name */
1017 int MMSoundMgrSessionSetDefaultSink (char *default_sink_name)
1018 {
1019         LOCK_SESSION();
1020
1021         strcpy (g_info.default_sink_name, default_sink_name);
1022         debug_msg ("[SESSION][%s][%d] default sink=[%s]\n", __func__, __LINE__, default_sink_name);
1023
1024         /* ToDo: do something */
1025
1026         UNLOCK_SESSION();
1027
1028         return MM_ERROR_NONE;
1029 }
1030
1031 /* DEVICE : Called by mgr_pulse for bt and mgr_headset for headset */
1032 int MMSoundMgrSessionSetDeviceAvailable (device_type_t device, int available, int type, char* name)
1033 {
1034         LOCK_SESSION();
1035
1036         debug_msg ("[SESSION] device = %d, available = %d, type = %d, name = %s\n", device, available, type, name);
1037         switch (device) {
1038         case DEVICE_WIRED:
1039                 if (available) {
1040
1041                         if (!IS_AVAILABLE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY)) {
1042                                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY);
1043                                 if (type == EARJACK_WITH_MIC) {
1044                                         SET_AVAILABLE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY);
1045                                         _mm_sound_mgr_device_available_device_callback(
1046                                                                                         MM_SOUND_DEVICE_IN_WIRED_ACCESSORY,
1047                                                                                         MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY,
1048                                                                                         AVAILABLE);
1049                                 } else {
1050                                         _mm_sound_mgr_device_available_device_callback(
1051                                                                                         MM_SOUND_DEVICE_IN_NONE,
1052                                                                                         MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY,
1053                                                                                         AVAILABLE);
1054                                 }
1055                                 __handle_headset_on(type);
1056                         } else {
1057                                 debug_log ("Already device [%d] is available...\n", device);
1058                         }
1059
1060                 } else {
1061
1062                         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY)) {
1063                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY);
1064                                 if (IS_AVAILABLE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY)) {
1065                                         UNSET_AVAILABLE(MM_SOUND_DEVICE_IN_WIRED_ACCESSORY);
1066                                         _mm_sound_mgr_device_available_device_callback(
1067                                                                                         MM_SOUND_DEVICE_IN_WIRED_ACCESSORY,
1068                                                                                         MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY,
1069                                                                                         NOT_AVAILABLE);
1070
1071                                 } else {
1072                                         _mm_sound_mgr_device_available_device_callback(
1073                                                                                         MM_SOUND_DEVICE_IN_NONE,
1074                                                                                         MM_SOUND_DEVICE_OUT_WIRED_ACCESSORY,
1075                                                                                         NOT_AVAILABLE);
1076                                 }
1077                                 __handle_headset_off();
1078                         } else {
1079                                 debug_log ("Already device [%d] is unavailable...\n", device);
1080                         }
1081
1082                 }
1083                 break;
1084
1085         case DEVICE_BT_A2DP:
1086                 strcpy (g_info.bt_name, (name)? name : "");
1087                 if (available) {
1088                         if (!IS_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_A2DP)) {
1089                                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_A2DP);
1090                                 _mm_sound_mgr_device_available_device_callback(
1091                                                                                         MM_SOUND_DEVICE_IN_NONE,
1092                                                                                         MM_SOUND_DEVICE_OUT_BT_A2DP,
1093                                                                                         AVAILABLE);
1094
1095                                 __handle_bt_a2dp_on();
1096                         } else {
1097                                 debug_log ("Already device [%d] is available...\n", device);
1098                         }
1099                 } else {
1100                         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_A2DP)) {
1101                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_A2DP);
1102                                 _mm_sound_mgr_device_available_device_callback(
1103                                                                                         MM_SOUND_DEVICE_IN_NONE,
1104                                                                                         MM_SOUND_DEVICE_OUT_BT_A2DP,
1105                                                                                         NOT_AVAILABLE);
1106
1107                                 __handle_bt_a2dp_off();
1108                         } else {
1109                                 debug_log ("Already device [%d] is unavailable...\n", device);
1110                         }
1111                 }
1112                 break;
1113
1114         case DEVICE_BT_SCO:
1115                 if (available) {
1116                         if (!IS_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_SCO)) {
1117                                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_SCO);
1118                                 SET_AVAILABLE(MM_SOUND_DEVICE_IN_BT_SCO);
1119                                 _mm_sound_mgr_device_available_device_callback(
1120                                                                                         MM_SOUND_DEVICE_IN_BT_SCO,
1121                                                                                         MM_SOUND_DEVICE_OUT_BT_SCO,
1122                                                                                         AVAILABLE);
1123                         } else {
1124                                 debug_log ("Already device [%d] is available...\n", device);
1125                         }
1126                 } else {
1127                         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_SCO)) {
1128                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_BT_SCO);
1129                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_IN_BT_SCO);
1130                                 _mm_sound_mgr_device_available_device_callback(
1131                                                                                         MM_SOUND_DEVICE_IN_BT_SCO,
1132                                                                                         MM_SOUND_DEVICE_OUT_BT_SCO,
1133                                                                                         NOT_AVAILABLE);
1134
1135                                 __handle_bt_sco_off();
1136                         } else {
1137                                 debug_log ("Already device [%d] is unavailable...\n", device);
1138                         }
1139                 }
1140                 break;
1141
1142         case DEVICE_DOCK:
1143                 if (available) {
1144                         if (!IS_AVAILABLE(MM_SOUND_DEVICE_OUT_DOCK)) {
1145                                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_DOCK);
1146                                 _mm_sound_mgr_device_available_device_callback(
1147                                                                                         MM_SOUND_DEVICE_IN_NONE,
1148                                                                                         MM_SOUND_DEVICE_OUT_DOCK,
1149                                                                                         AVAILABLE);
1150                                 __handle_dock_on();
1151                         } else {
1152                                 debug_log ("Already device [%d] is available...\n", device);
1153                         }
1154                 } else {
1155                         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_DOCK)) {
1156                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_DOCK);
1157                                 _mm_sound_mgr_device_available_device_callback(
1158                                                                                         MM_SOUND_DEVICE_IN_NONE,
1159                                                                                         MM_SOUND_DEVICE_OUT_DOCK,
1160                                                                                         NOT_AVAILABLE);
1161
1162                                 __handle_dock_off();
1163                         } else {
1164                                 debug_log ("Already device [%d] is unavailable...\n", device);
1165                         }
1166                 }
1167                 break;
1168
1169         case DEVICE_HDMI:
1170                 if (available) {
1171                         if (!IS_AVAILABLE(MM_SOUND_DEVICE_OUT_HDMI)) {
1172                                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_HDMI);
1173                                 _mm_sound_mgr_device_available_device_callback(
1174                                                                                         MM_SOUND_DEVICE_IN_NONE,
1175                                                                                         MM_SOUND_DEVICE_OUT_HDMI,
1176                                                                                         AVAILABLE);
1177                                 __handle_hdmi_on();
1178                         } else {
1179                                 debug_log ("Already device [%d] is available...\n", device);
1180                         }
1181                 } else {
1182                         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_HDMI)) {
1183                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_HDMI);
1184                                 _mm_sound_mgr_device_available_device_callback(
1185                                                                                         MM_SOUND_DEVICE_IN_NONE,
1186                                                                                         MM_SOUND_DEVICE_OUT_HDMI,
1187                                                                                         NOT_AVAILABLE);
1188
1189                                 __handle_hdmi_off();
1190                         } else {
1191                                 debug_log ("Already device [%d] is unavailable...\n", device);
1192                         }
1193                 }
1194                 break;
1195
1196         case DEVICE_WFD:
1197                 if (available) {
1198                         if (!IS_AVAILABLE(MM_SOUND_DEVICE_OUT_WFD)) {
1199                                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_WFD);
1200                                 _mm_sound_mgr_device_available_device_callback(
1201                                                                                         MM_SOUND_DEVICE_IN_NONE,
1202                                                                                         MM_SOUND_DEVICE_OUT_WFD,
1203                                                                                         AVAILABLE);
1204                                 __handle_wfd_on();
1205                         } else {
1206                                 debug_log ("Already device [%d] is available...\n", device);
1207                         }
1208                 } else {
1209                         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_WFD)) {
1210                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_WFD);
1211                                 _mm_sound_mgr_device_available_device_callback(
1212                                                                                         MM_SOUND_DEVICE_IN_NONE,
1213                                                                                         MM_SOUND_DEVICE_OUT_WFD,
1214                                                                                         NOT_AVAILABLE);
1215
1216                                 __handle_wfd_off();
1217                         } else {
1218                                 debug_log ("Already device [%d] is unavailable...\n", device);
1219                         }
1220                 }
1221                 break;
1222
1223         case DEVICE_USB_AUDIO:
1224                 if (available) {
1225                         if (!IS_AVAILABLE(MM_SOUND_DEVICE_OUT_USB_AUDIO)) {
1226                                 SET_AVAILABLE(MM_SOUND_DEVICE_OUT_USB_AUDIO);
1227                                 _mm_sound_mgr_device_available_device_callback(
1228                                                                                         MM_SOUND_DEVICE_IN_NONE,
1229                                                                                         MM_SOUND_DEVICE_OUT_USB_AUDIO,
1230                                                                                         AVAILABLE);
1231                                 __handle_usb_audio_on();
1232                         } else {
1233                                 debug_log ("Already device [%d] is available...\n", device);
1234                         }
1235                 } else {
1236                         if (IS_AVAILABLE(MM_SOUND_DEVICE_OUT_USB_AUDIO)) {
1237                                 UNSET_AVAILABLE(MM_SOUND_DEVICE_OUT_USB_AUDIO);
1238                                 _mm_sound_mgr_device_available_device_callback(
1239                                                                                         MM_SOUND_DEVICE_IN_NONE,
1240                                                                                         MM_SOUND_DEVICE_OUT_USB_AUDIO,
1241                                                                                         NOT_AVAILABLE);
1242
1243                                 __handle_usb_audio_off();
1244                         } else {
1245                                 debug_log ("Already device [%d] is unavailable...\n", device);
1246                         }
1247                 }
1248                 break;
1249
1250         default:
1251                 debug_warning ("device [%d] is not handled...\n", device);
1252                 break;
1253         }
1254
1255         UNLOCK_SESSION();
1256
1257         return MM_ERROR_NONE;
1258 }
1259
1260 int MMSoundMgrSessionIsDeviceAvailableNoLock (mm_sound_device_out playback, mm_sound_device_in capture, bool *available)
1261 {
1262         int ret = MM_ERROR_NONE;
1263         debug_log ("[SESSION][%s][%d] query playback=[0x%X] capture=[0x%X], current available = [0x%X]\n",
1264                         __func__, __LINE__, playback, capture, g_info.device_available);
1265
1266         if (available) {
1267                 if (playback == MM_SOUND_DEVICE_OUT_NONE) {
1268                         *available = IS_AVAILABLE(capture);
1269                 } else if (capture == MM_SOUND_DEVICE_IN_NONE) {
1270                         *available = IS_AVAILABLE(playback);
1271                 } else {
1272                         *available = (IS_AVAILABLE(playback) && IS_AVAILABLE(capture));
1273                 }
1274                 debug_log ("[%s][%d] return available = [%d]\n", __func__, __LINE__, *available);
1275         } else {
1276                 debug_warning ("Invalid argument!!!\n");
1277                 ret = MM_ERROR_INVALID_ARGUMENT;
1278         }
1279
1280         return ret;
1281 }
1282
1283
1284 int MMSoundMgrSessionIsDeviceAvailable (mm_sound_device_out playback, mm_sound_device_in capture, bool *available)
1285 {
1286         int ret = MM_ERROR_NONE;
1287
1288         LOCK_SESSION();
1289         ret = MMSoundMgrSessionIsDeviceAvailableNoLock (playback, capture, available);
1290         UNLOCK_SESSION();
1291
1292         return ret;
1293 }
1294
1295 int MMSoundMgrSessionGetAvailableDevices (int *playback, int *capture)
1296 {
1297         if (playback == NULL || capture == NULL) {
1298                 debug_error ("Invalid input parameter\n");
1299                 return MM_ERROR_INVALID_ARGUMENT;
1300         }
1301
1302         LOCK_SESSION();
1303
1304         *playback = GET_AVAILABLE_PLAYBACK();
1305         *capture  = GET_AVAILABLE_CAPTURE();
1306         debug_msg ("[SESSION][%s][%d] return available playback=[0x%X]/capture=[0x%X]\n", __func__, __LINE__, *playback, *capture);
1307
1308         UNLOCK_SESSION();
1309
1310         return MM_ERROR_NONE;
1311 }
1312
1313 int MMSoundMgrSessionSetDeviceActive (mm_sound_device_out playback, mm_sound_device_in capture)
1314 {
1315         int ret = MM_ERROR_NONE;
1316         int old_active = g_info.device_active;
1317
1318         LOCK_SESSION();
1319
1320         debug_msg ("[SESSION][%s][%d] playback=[0x%X] capture=[0x%X]\n", __func__, __LINE__, playback, capture);
1321
1322         /* Check whether device is available */
1323         if ((playback && !IS_AVAILABLE(playback)) || (capture && !IS_AVAILABLE(capture))) {
1324                 debug_warning ("Failed to set active state to unavailable device!!!\n");
1325                 ret = MM_ERROR_INVALID_ARGUMENT;
1326                 goto END_SET_DEVICE;
1327         }
1328
1329         /* Update active state */
1330         debug_log ("Update active device as request\n");
1331         if (playback) {
1332                 SET_PLAYBACK_ONLY_ACTIVE(playback);
1333         }
1334         if (capture) {
1335                 SET_CAPTURE_ONLY_ACTIVE(capture);
1336         }
1337
1338         /* If there's changes do path set and inform callback */
1339         if (old_active != g_info.device_active) {
1340                 debug_msg ("Changes happens....set path based on current active device and inform callback!!!\n");
1341
1342                 /* Do set path based on current active state */
1343                 __set_path_with_notification(DO_NOTI);
1344         } else {
1345                 debug_msg ("No changes....nothing to do...\n");
1346         }
1347
1348 END_SET_DEVICE:
1349         UNLOCK_SESSION();
1350         return ret;
1351 }
1352
1353 int MMSoundMgrSessionGetDeviceActive (mm_sound_device_out *playback, mm_sound_device_in *capture)
1354 {
1355         if (playback == NULL || capture == NULL) {
1356                 debug_error ("Invalid input parameter\n");
1357                 return MM_ERROR_INVALID_ARGUMENT;
1358         }
1359
1360         LOCK_SESSION();
1361
1362         *playback = GET_ACTIVE_PLAYBACK();
1363         *capture  = GET_ACTIVE_CAPTURE();
1364         debug_msg ("[SESSION][%s][%d] return active playback=[0x%X]/capture=[0x%X]\n", __func__, __LINE__,
1365                                 *playback,*capture);
1366
1367         UNLOCK_SESSION();
1368         return MM_ERROR_NONE;
1369 }
1370
1371 /* SUBSESSION */
1372 int MMSoundMgrSessionSetSession(session_t session, session_state_t state)
1373 {
1374         LOCK_SESSION();
1375
1376         debug_warning ("[SESSION][%s][%d] session=[%d] state=[%d]\n", __func__, __LINE__, session, state);
1377
1378         /* Update session */
1379         if (state)
1380                 g_info.session = session;
1381         else
1382                 g_info.session = SESSION_MEDIA;
1383
1384         /* Do action based on new session */
1385         switch (session) {
1386         case SESSION_MEDIA:
1387                 /* ToDo:
1388                 start
1389                         mic setting
1390                 end
1391                 */
1392                 break;
1393
1394         case SESSION_VOICECALL:
1395         case SESSION_VOIP:
1396                 __set_playback_route_communication (state);
1397                 break;
1398
1399         case SESSION_FMRADIO:
1400                 __set_playback_route_fmradio (state);
1401                 break;
1402
1403         case SESSION_NOTIFICATION:
1404                 __set_playback_route_notification (state);
1405                 break;
1406
1407         case SESSION_EMERGENCY:
1408                 __set_playback_route_emergency (state);
1409                 break;
1410
1411         default:
1412                 debug_warning ("session [%d] is not handled...\n", session);
1413                 break;
1414         }
1415
1416         UNLOCK_SESSION();
1417         return MM_ERROR_NONE;
1418 }
1419
1420 int MMSoundMgrSessionGetSession(session_t *session)
1421 {
1422         if (session == NULL) {
1423                 debug_error ("Invalid input parameter\n");
1424                 return MM_ERROR_INVALID_ARGUMENT;
1425         }
1426
1427         //LOCK_SESSION();
1428         *session = g_info.session;
1429         //UNLOCK_SESSION();
1430
1431         return MM_ERROR_NONE;
1432 }
1433
1434 /* SUBSESSION */
1435 int MMSoundMgrSessionSetSubSession(subsession_t subsession)
1436 {
1437         LOCK_SESSION();
1438
1439         if (g_info.subsession == subsession) {
1440                 debug_msg ("[SESSION][%s][%d] already subsession is [%d]. skip this!!\n", __func__, __LINE__, subsession);
1441         } else {
1442                 g_info.subsession = subsession;
1443                 debug_msg ("[SESSION][%s][%d] subsession=[%d]\n", __func__, __LINE__, subsession);
1444
1445                 __set_path_with_notification (NO_NOTI);
1446         }
1447
1448         UNLOCK_SESSION();
1449
1450         return MM_ERROR_NONE;
1451 }
1452
1453 int MMSoundMgrSessionGetSubSession(subsession_t *subsession)
1454 {
1455         if (subsession == NULL) {
1456                 debug_error ("Invalid input parameter\n");
1457                 return MM_ERROR_INVALID_ARGUMENT;
1458         }
1459
1460         LOCK_SESSION();
1461
1462         *subsession = g_info.subsession;
1463
1464         UNLOCK_SESSION();
1465
1466         return MM_ERROR_NONE;
1467 }
1468
1469 char* MMSoundMgrSessionGetBtA2DPName ()
1470 {
1471         return g_info.bt_name;
1472 }
1473
1474 int MMSoundMgrSessionInit(void)
1475 {
1476         LOCK_SESSION();
1477
1478         debug_fenter();
1479
1480         memset (&g_info, 0, sizeof (SESSION_INFO_STRUCT));
1481
1482         /* FIXME: Initial status should be updated */
1483         __set_initial_active_device ();
1484
1485 #ifndef MURPHY
1486         /* Register for headset unplug */
1487         if (_asm_register_for_headset (&g_info.asm_handle) == false) {
1488                 debug_error ("Failed to register ASM for headset\n");
1489         }
1490 #endif
1491
1492         debug_fleave();
1493
1494         UNLOCK_SESSION();
1495         return MM_ERROR_NONE;
1496 }
1497
1498 int MMSoundMgrSessionFini(void)
1499 {
1500         LOCK_SESSION();
1501
1502         debug_fenter();
1503
1504 #ifndef MURPHY
1505         /* Unregister for headset unplug */
1506         _asm_unregister_for_headset (&g_info.asm_handle);
1507 #endif
1508
1509         debug_fleave();
1510
1511         UNLOCK_SESSION();
1512
1513         return MM_ERROR_NONE;
1514 }
1515