f56d73e6b9d6f8607d426087c8ecdc65f0a56eb9
[platform/core/api/audio-io.git] / src / cpp / CAudioSessionHandler.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <unistd.h>
19 #include <mm_error.h>
20 #include "CAudioIODef.h"
21
22
23 using namespace std;
24 using namespace tizen_media_audio;
25
26
27 /**
28  * class CAudioSessionHandler
29  */
30 int CAudioSessionHandler::__sCaptureRef = 0;
31
32 int CAudioSessionHandler::__pcmCaptureCountInc() {
33     int actual;
34     do {
35         actual = __sCaptureRef;
36     } while (!__sync_bool_compare_and_swap(&__sCaptureRef, actual, actual + 1));
37     AUDIO_IO_LOGD("CaptureRefCount+1 > [%d]", __sCaptureRef);
38     return __sCaptureRef;
39 }
40
41 int CAudioSessionHandler::__pcmCaptureCountDec() {
42     int actual;
43     do {
44         actual = __sCaptureRef;
45     } while (!__sync_bool_compare_and_swap(&__sCaptureRef, actual, actual - 1));
46     AUDIO_IO_LOGD("CaptureRefCount-1 > [%d]", __sCaptureRef);
47     if (__sCaptureRef < 0) {
48         AUDIO_IO_LOGE("A CaptureRef[%d] is not valid! Something is wrong!", __sCaptureRef);
49         __sCaptureRef = 0;
50     }
51     return __sCaptureRef;
52 }
53
54 int CAudioSessionHandler::__pcmCaptureCountGet() {
55     AUDIO_IO_LOGD("CaptureRefCount > [%d]", __sCaptureRef);
56     return __sCaptureRef;
57 }
58
59 int CAudioSessionHandler::__sFocusRef = 0;
60
61 int CAudioSessionHandler::__focusIdCountInc() {
62     int actual;
63     do {
64         actual = __sFocusRef;
65     } while (!__sync_bool_compare_and_swap(&__sFocusRef, actual, actual + 1));
66     AUDIO_IO_LOGD("FocusRefCount+1 > [%d]", __sFocusRef);
67     return __sFocusRef;
68 }
69
70 int CAudioSessionHandler::__focusIdCountDec() {
71     int actual;
72     do {
73         actual = __sFocusRef;
74     } while (!__sync_bool_compare_and_swap(&__sFocusRef, actual, actual - 1));
75     AUDIO_IO_LOGD("FocusRefCount-1 > [%d]", __sFocusRef);
76     return __sFocusRef;
77 }
78
79 int CAudioSessionHandler::__focusIdCountGet() {
80     /* AUDIO_IO_LOGD("FocusRefCount > [%d]", __sFocusRef); */
81     return __sFocusRef;
82 }
83
84 void CAudioSessionHandler::__lockFocusCBMutex() {
85     if (pthread_mutex_lock(&__mFocusCBMutex) != 0) {
86         THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
87     }
88 #ifdef _AUDIO_IO_DEBUG_TIMING_
89     AUDIO_IO_LOGD(COLOR_RED "LOCK - FocusCB Mutex" COLOR_END);
90 #endif
91 }
92
93 void CAudioSessionHandler::__unlockFocusCBMutex() {
94     if (pthread_mutex_unlock(&__mFocusCBMutex) != 0) {
95         THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_unlock()");
96     }
97 #ifdef _AUDIO_IO_DEBUG_TIMING_
98     AUDIO_IO_LOGD(COLOR_GREEN "UNLOCK - FocusCB Mutex" COLOR_END);
99 #endif
100 }
101
102 CAudioSessionHandler::CAudioSessionHandler(EAudioSessionType sessionType, CAudioInfo& audioInfo, IAudioSessionEventListener* listener) :
103     __mId(-1),
104     __mOptions(0),
105     __mAudioSession(sessionType),
106     __mMultimediaSession(MM_SESSION_TYPE_MEDIA),
107     __mpEventListener(listener),
108     __mIsInit(false),
109     __mSubscribeId(0),
110     __mUseFocus(false),
111     __mAcquiredFocus(FOCUS_NONE),
112     __mReasonForChange(NULL),
113     __mAdditionalInfo(NULL),
114     __mFocusCBMutex(PTHREAD_MUTEX_INITIALIZER) {
115     __mAudioInfo = audioInfo;
116 }
117
118 CAudioSessionHandler::~CAudioSessionHandler() {
119 }
120
121 CAudioError CAudioSessionHandler::__convertStreamType(EAudioSessionType type1, MMSessionType type2, int *index) {
122     unsigned int i;
123     int idx = -1;
124
125     assert(index != NULL);
126
127     if (type1 == EAudioSessionType::AUDIO_SESSION_TYPE_CAPTURE) {
128         for (i = 0 ; i < sizeof(__STREAM_TYPE_TABLE_IN) / sizeof(__STREAM_TYPE_TABLE_IN[0]) ; i++) {
129             if (__STREAM_TYPE_TABLE_IN[i].type == type2) {
130                 idx = i;
131                 break;
132             }
133         }
134     } else {
135         for (i = 0 ; i < sizeof(__STREAM_TYPE_TABLE_OUT) / sizeof(__STREAM_TYPE_TABLE_OUT[0]) ; i++) {
136             if (__STREAM_TYPE_TABLE_OUT[i].type == type2) {
137                 idx = i;
138                 break;
139             }
140         }
141     }
142
143     if (idx < 0) {
144         RET_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "Does not support session type.");
145     }
146     *index = idx;
147     RET_ERROR(CAudioError::EError::ERROR_NONE);
148 }
149
150 CAudioError CAudioSessionHandler::__getAsmInformation(MMSessionType *type, int *options) {
151     assert(type != NULL);
152     assert(options != NULL);
153
154     MMSessionType currentSession = MM_SESSION_TYPE_MEDIA;
155     int           sessionOptions = 0;
156
157     /* Read session information */
158     int ret = 0;
159     if ((ret = _mm_session_util_read_information(-1, (int*)&currentSession, &sessionOptions)) < 0) {
160         if (ret == (int) MM_ERROR_INVALID_HANDLE) {
161             RET_ERROR_MSG(CAudioError::EError::ERROR_INVALID_HANDLE, "Failed _mm_session_util_read_information(). Invalid handle");
162         } else {
163             RET_ERROR_MSG(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed _mm_session_util_read_information(). Not exist");
164         }
165     }
166
167     *type    = currentSession;
168     *options = sessionOptions;
169
170     RET_ERROR(CAudioError::EError::ERROR_NONE);
171 }
172
173 bool CAudioSessionHandler::__isFocusRequired(MMSessionType type, int options) {
174     if ((options & MM_SESSION_OPTION_PAUSE_OTHERS)
175         || ((type != MM_SESSION_TYPE_MEDIA) && (type != MM_SESSION_TYPE_MEDIA_RECORD)))
176         return true;
177     else
178         return false;
179 }
180
181 bool CAudioSessionHandler::__isFocusDisableReacquisitionRequired(MMSessionType type, int options) {
182     if ((type == MM_SESSION_TYPE_MEDIA) &&
183         !(options & MM_SESSION_OPTION_RESUME_BY_SYSTEM_OR_MEDIA_PAUSED))
184         return true;
185
186     return false;
187 }
188
189 int CAudioSessionHandler::getId() {
190     return __mId;
191 }
192
193 int CAudioSessionHandler::getOptions() {
194     return __mOptions;
195 }
196
197 CAudioSessionHandler::EAudioSessionType CAudioSessionHandler::getAudioSession() {
198     return __mAudioSession;
199 }
200
201 MMSessionType CAudioSessionHandler::getMultimediaSession() {
202     return __mMultimediaSession;
203 }
204
205 void CAudioSessionHandler::getInternalVoipStreamInfo(sound_stream_info_h *stream_info) {
206     int ret;
207
208     if ((ret = sound_manager_get_internal_voip_stream_information(stream_info))) {
209         if (ret == SOUND_MANAGER_ERROR_NO_DATA) {
210             AUDIO_IO_LOGW("there's no internal voip stream info.");
211         } else {
212             AUDIO_IO_LOGE("failed to sound_manager_get_internal_voip_stream_information(), ret(0x%x)", ret);
213         }
214     }
215     return;
216 }
217
218 unsigned int CAudioSessionHandler::getSubscribeId() {
219     return __mSubscribeId;
220 }
221
222 CAudioInfo CAudioSessionHandler::getAudioInfo() {
223     return __mAudioInfo;
224 }
225
226 void CAudioSessionHandler::__sound_pcm_signal_cb(mm_sound_signal_name_t signal, int value, void *user_data) {
227     assert(user_data);
228
229     AUDIO_IO_LOGD("[signal:%d], [value:%d], [user_data:%p]", signal, value, user_data);
230
231     CAudioSessionHandler* pHandler = static_cast<CAudioSessionHandler*>(user_data);
232     if (pHandler->__mpEventListener != NULL)
233         pHandler->__mpEventListener->onSignal(pHandler, signal, value);
234 }
235
236 void CAudioSessionHandler::initialize() {
237     AUDIO_IO_LOGD("");
238     if (__mIsInit == true) {
239         return;
240     }
241
242     MMSessionType currentSession = MM_SESSION_TYPE_MEDIA;
243     int           sessionOptions = 0;  // Mix with others by default
244
245     CAudioError err = __getAsmInformation(&currentSession, &sessionOptions);
246     if (err == CAudioError::EError::ERROR_NONE) {
247         if (currentSession == MM_SESSION_TYPE_REPLACED_BY_STREAM) {
248             __mUseFocus = false;
249             AUDIO_IO_LOGD("Stream info. was created outside, skip audio focus concept internally!");
250         } else {
251             // Session was configured before, use focus callback
252             __mUseFocus = true;
253             AUDIO_IO_LOGD("Use audio focus concept internally!");
254         }
255     } else {
256         if (err == CAudioError::EError::ERROR_INVALID_HANDLE) {
257             // No session, No stream_info, No focus watch callback before
258             // Use focus watch callback with signal subscribe
259
260             int errorCode = mm_sound_subscribe_signal(MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS, &__mSubscribeId, __sound_pcm_signal_cb, static_cast<void*>(this));
261             if (errorCode != MM_ERROR_NONE || __mSubscribeId == 0) {
262                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_subscribe_signal() err:0x%x, __mSubscribeId:%u",
263                                        errorCode, __mSubscribeId);
264             }
265
266             AUDIO_IO_LOGD("Subscribed mm_sound signal [id:%d]", __mSubscribeId);
267
268             sessionOptions = 0;  // Mix with others by default
269             __mUseFocus = true;
270             AUDIO_IO_LOGD("Use audio focus(watch) concept internally!");
271         } else {
272             __mUseFocus = false;
273             AUDIO_IO_LOGD("Skip audio focus concept!");
274         }
275
276         if (__mAudioSession == EAudioSessionType::AUDIO_SESSION_TYPE_CAPTURE) {
277             AUDIO_IO_LOGD("Set default \"Media_Record\" type");
278             currentSession = MM_SESSION_TYPE_MEDIA_RECORD;
279         } else {
280             AUDIO_IO_LOGD("Set default \"Media\" type");
281             currentSession = MM_SESSION_TYPE_MEDIA;
282         }
283     }
284
285     // Updates session information
286     __mMultimediaSession = currentSession;
287     __mOptions           = sessionOptions;
288
289     if (this->__mAudioSession == EAudioSessionType::AUDIO_SESSION_TYPE_CAPTURE) {
290         __pcmCaptureCountInc();
291     }
292
293     __mIsInit = true;
294 }
295
296 void CAudioSessionHandler::finalize() {
297     AUDIO_IO_LOGD("");
298     if (__mIsInit == false) {
299         return;
300     }
301
302     if (__mAudioSession == EAudioSessionType::AUDIO_SESSION_TYPE_CAPTURE) {
303         __pcmCaptureCountDec();
304     }
305
306     unregisterSound();
307
308     if (__mSubscribeId > 0) {
309         AUDIO_IO_LOGD("Unsubscribed mm_sound signal [id:%d]", __mSubscribeId);
310         mm_sound_unsubscribe_signal(__mSubscribeId);
311         __mSubscribeId = 0;
312     }
313
314     __mpEventListener = NULL;
315
316     __mIsInit = false;
317 }
318
319 bool CAudioSessionHandler::isSkipSession() {
320     if (__mMultimediaSession == MM_SESSION_TYPE_REPLACED_BY_STREAM ||
321         __mMultimediaSession == MM_SESSION_TYPE_VOIP ||
322         __mMultimediaSession == MM_SESSION_TYPE_CALL ||
323         __mMultimediaSession == MM_SESSION_TYPE_VIDEOCALL) {
324         AUDIO_IO_LOGD("__mMultimediaSession is [%d], skip session", __mMultimediaSession);
325         return true;
326     }
327
328     return false;
329 }
330
331 void CAudioSessionHandler::__sound_pcm_focus_cb(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state,
332                                                 const char *reason_for_change, int option, const char *additional_info, void *user_data) {
333     assert(user_data);
334
335     AUDIO_IO_LOGD("[id:%d], [focus_type:%d], [state:%d], [reason_for_change:%s], [additional_info:%s], [user_data:%p]",
336                   id, focus_type, state, reason_for_change, additional_info, user_data);
337
338 /* FIXME: disable it temporarily */
339 #ifndef DISABLE_SESSION_BACK_COMP
340
341     CAudioSessionHandler* pHandler = static_cast<CAudioSessionHandler*>(user_data);
342
343     pHandler->__lockFocusCBMutex();
344
345     if (state == FOCUS_IS_RELEASED)
346         pHandler->__mAcquiredFocus &= ~focus_type;
347     else if (state == FOCUS_IS_ACQUIRED)
348         pHandler->__mAcquiredFocus |= focus_type;
349     pHandler->__mReasonForChange = (char *)reason_for_change;
350     pHandler->__mAdditionalInfo  = (char *)additional_info;
351
352     if (pHandler->__mpEventListener != NULL)
353         pHandler->__mpEventListener->onInterrupt(pHandler, id, focus_type, state, reason_for_change, additional_info);
354
355     pHandler->__unlockFocusCBMutex();
356 #endif
357     return;
358 }
359
360 void CAudioSessionHandler::__sound_pcm_focus_watch_cb(int id, mm_sound_focus_type_e focus_type, mm_sound_focus_state_e state,
361                                                       const char *reason_for_change, const char *additional_info, void *user_data) {
362     AUDIO_IO_LOGD("[id:%d], [focus_type:%d], [state:%d], [reason_for_change:%s], [additional_info:%s], [user_data:%p]",
363                   id, focus_type, state, reason_for_change, additional_info, user_data);
364
365     CAudioSessionHandler::__sound_pcm_focus_cb(-1, focus_type, state, reason_for_change, 0, additional_info, user_data);
366
367     return;
368 }
369
370 void CAudioSessionHandler::registerSound() {
371     if (__mIsInit == false) {
372         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
373     }
374
375     if (__mUseFocus == true) {
376         if (__mId >= 0) {
377             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_POLICY_BLOCKED, "Already registered [id:%d]", __mId);
378         }
379
380         int errorCode = 0;
381
382         if (__isFocusRequired(__mMultimediaSession, __mOptions)) {
383             int index = 0;
384
385             CAudioError err = __convertStreamType(__mAudioSession, __mMultimediaSession, &index);
386             if (err != CAudioError::EError::ERROR_NONE) {
387                 throw err;
388             }
389
390             errorCode = mm_sound_focus_get_id(&__mId);
391             if (errorCode != MM_ERROR_NONE) {
392                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_focus_get_id() err:0x%x", errorCode);
393             }
394
395             // Register focus callback
396             errorCode = mm_sound_register_focus_for_session(__mId,
397                                                 getpid(),
398                                                 __mAudioSession == EAudioSessionType::AUDIO_SESSION_TYPE_CAPTURE ? __STREAM_TYPE_TABLE_IN[index].name : __STREAM_TYPE_TABLE_OUT[index].name,
399                                                 __sound_pcm_focus_cb,
400                                                 static_cast<void*>(this));
401             if (errorCode != MM_ERROR_NONE) {
402                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_register_focus_for_session() err:0x%x", errorCode);
403             }
404
405             if (__isFocusDisableReacquisitionRequired(__mMultimediaSession, __mOptions)) {
406                 errorCode = mm_sound_set_focus_reacquisition_for_session(__mId, false);
407                 if (errorCode != MM_ERROR_NONE) {
408                     THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_set_focus_reacquisition() err:0x%x", errorCode);
409                 }
410             }
411
412             __focusIdCountInc();
413
414             AUDIO_IO_LOGD("Focus callback registered successfully [id:%d]", __mId);
415         } else if (!(__mOptions & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
416             // Register focus watch callback
417             errorCode = mm_sound_set_focus_watch_callback_for_session(getpid(), FOCUS_FOR_BOTH, __sound_pcm_focus_watch_cb, static_cast<void*>(this), &__mId);
418             if (errorCode < 0) {
419                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_set_focus_watch_callback_for_session() err:0x%x", errorCode);
420             }
421
422             __focusIdCountInc();
423
424             AUDIO_IO_LOGD("Focus watch callback registered successfully [id:%d]", __mId);
425         }
426     }
427 }
428
429 void CAudioSessionHandler::unregisterSound() {
430     if (__mIsInit == false) {
431         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
432     }
433
434     if (__mUseFocus == true && __mId >= 0) {
435         int errorCode = 0;
436
437         if (__isFocusRequired(__mMultimediaSession, __mOptions)) {
438             // Unregister focus callback
439             errorCode = mm_sound_unregister_focus(__mId);
440             if (errorCode != MM_ERROR_NONE) {
441                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_unregister_focus() err:0x%x", errorCode);
442             }
443
444             __focusIdCountDec();
445
446             AUDIO_IO_LOGD("Focus callback unregistered successfully [id:%d]", __mId);
447             __mId = -1;
448         } else if (!(__mOptions & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
449             // Unregister focus watch callback.
450             errorCode = mm_sound_unset_focus_watch_callback(__mId);
451             if (errorCode < 0) {
452                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_unset_focus_watch_callback() err:0x%x", errorCode);
453             }
454
455             __focusIdCountDec();
456
457             AUDIO_IO_LOGD("Focus watch callback unregistered successfully [id:%d]", __mId);
458             __mId = -1;
459         }
460         __mAcquiredFocus = FOCUS_NONE;
461     }
462 }
463
464 void CAudioSessionHandler::updatePlaying() {
465     if (__mIsInit == false) {
466         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
467     }
468
469     if (__mUseFocus && __isFocusRequired(__mMultimediaSession, __mOptions)) {
470         if (__mId >= 0) {
471             int ret = MM_ERROR_NONE;
472             int focus_type = 0;
473             bool is_focus_cb_thread;
474
475             if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
476                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed mm_sound_focus_is_cb_thread() err:0x%x", ret);
477
478             if (!is_focus_cb_thread)
479                 __lockFocusCBMutex();
480
481             if (__mAcquiredFocus == FOCUS_FOR_BOTH) {
482                 AUDIO_IO_LOGW("Focus was already acquired, skip it...");
483                 if (!is_focus_cb_thread)
484                     __unlockFocusCBMutex();
485                 return;
486             }
487
488             focus_type |= (FOCUS_FOR_BOTH & ~__mAcquiredFocus);
489             if (__mMultimediaSession == MM_SESSION_TYPE_MEDIA)
490                 ret = mm_sound_acquire_focus_with_option(__mId, (mm_sound_focus_type_e)focus_type, 1, "audio-io acquire focus"); /* option: 1 for no-resume */
491             else
492                 ret = mm_sound_acquire_focus(__mId, (mm_sound_focus_type_e)focus_type, "audio-io acquire focus");
493             if (ret != MM_ERROR_NONE) {
494                 if (!is_focus_cb_thread)
495                     __unlockFocusCBMutex();
496                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_POLICY_BLOCKED, "Failed mm_sound_acquire_focus() err:0x%x", ret);
497             }
498             __mAcquiredFocus = FOCUS_FOR_BOTH;
499             AUDIO_IO_LOGD("Focus acquired successfully [id:%d]", __mId);
500
501             if (!is_focus_cb_thread)
502                 __unlockFocusCBMutex();
503         }
504     }
505 }
506
507 void CAudioSessionHandler::updateStop() {
508     if (__mIsInit == false) {
509         THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
510     }
511
512     if (__mUseFocus && __isFocusRequired(__mMultimediaSession, __mOptions)) {
513         if (__mId >= 0) {
514             int ret = MM_ERROR_NONE;
515             bool is_focus_cb_thread;
516
517             if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
518                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed mm_sound_focus_is_cb_thread() err:0x%x", ret);
519
520             if (!is_focus_cb_thread)
521                 __lockFocusCBMutex();
522
523             if (__mAcquiredFocus == FOCUS_NONE) {
524                 AUDIO_IO_LOGW("Focus was already released, skip it...");
525                 if (!is_focus_cb_thread)
526                     __unlockFocusCBMutex();
527                 return;
528             }
529
530             if (__mMultimediaSession == MM_SESSION_TYPE_MEDIA)
531                 ret = mm_sound_release_focus_with_option(__mId, (mm_sound_focus_type_e)__mAcquiredFocus, 1, "audio-io release focus"); /* option: 1 for no-resume */
532             else
533                 ret = mm_sound_release_focus(__mId, (mm_sound_focus_type_e)__mAcquiredFocus, "audio-io release focus");
534             if (ret != MM_ERROR_NONE) {
535                 if (!is_focus_cb_thread)
536                     __unlockFocusCBMutex();
537                 THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_release_focus() err:0x%x", ret);
538             }
539             __mAcquiredFocus = FOCUS_NONE;
540             AUDIO_IO_LOGD("Focus released successfully [id:%d]", __mId);
541
542             if (!is_focus_cb_thread)
543                 __unlockFocusCBMutex();
544         }
545     }
546 }
547
548 void CAudioSessionHandler::disableSessionHandler() {
549     CAudioSessionHandler::updateStop();
550     CAudioSessionHandler::unregisterSound();
551
552     CAudioSessionHandler::__mUseFocus = false;
553 }
554
555 /**
556  * class IAudioSessionEventListener
557  */
558 IAudioSessionEventListener::EInterruptCode IAudioSessionEventListener::convertInterruptedCode(int code, const char *reason_for_change) {
559     EInterruptCode e = EInterruptCode::INTERRUPT_BY_MEDIA;
560
561     switch (code) {
562     case FOCUS_IS_ACQUIRED:
563         e = EInterruptCode::INTERRUPT_COMPLETED;
564         break;
565
566     case FOCUS_IS_RELEASED:
567         if (!strcmp(reason_for_change, "media"))              e = EInterruptCode::INTERRUPT_BY_MEDIA;
568         if (!strcmp(reason_for_change, "radio"))              e = EInterruptCode::INTERRUPT_BY_MEDIA;
569         if (!strcmp(reason_for_change, "loopback"))           e = EInterruptCode::INTERRUPT_BY_MEDIA;
570         if (!strcmp(reason_for_change, "system"))             e = EInterruptCode::INTERRUPT_BY_MEDIA;
571         if (!strcmp(reason_for_change, "alarm"))              e = EInterruptCode::INTERRUPT_BY_ALARM;
572         if (!strcmp(reason_for_change, "notification"))       e = EInterruptCode::INTERRUPT_BY_NOTIFICATION;
573         if (!strcmp(reason_for_change, "emergency"))          e = EInterruptCode::INTERRUPT_BY_EMERGENCY;
574         if (!strcmp(reason_for_change, "voice-information"))  e = EInterruptCode::INTERRUPT_BY_MEDIA;
575         if (!strcmp(reason_for_change, "voice-recognition"))  e = EInterruptCode::INTERRUPT_BY_MEDIA;
576         if (!strcmp(reason_for_change, "voice-recognition-service")) e = EInterruptCode::INTERRUPT_BY_MEDIA;
577         if (!strcmp(reason_for_change, "ringtone-voip"))      e = EInterruptCode::INTERRUPT_BY_CALL;
578         if (!strcmp(reason_for_change, "ringtone-call"))      e = EInterruptCode::INTERRUPT_BY_CALL;
579         if (!strcmp(reason_for_change, "voip"))               e = EInterruptCode::INTERRUPT_BY_CALL;
580         if (!strcmp(reason_for_change, "call-voice"))         e = EInterruptCode::INTERRUPT_BY_CALL;
581         if (!strcmp(reason_for_change, "call-video"))         e = EInterruptCode::INTERRUPT_BY_CALL;
582         break;
583     }
584
585     return e;
586 }