return __sFocusRef;
}
+void CAudioSessionHandler::__lockFocusIdMutex() {
+ if (pthread_mutex_lock(&__mFocusIdMutex) != 0) {
+ THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock() - FocusId Mutex");
+ }
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD(COLOR_RED "LOCK - FocusId Mutex" COLOR_END);
+#endif
+}
+
+void CAudioSessionHandler::__unlockFocusIdMutex() {
+ if (pthread_mutex_unlock(&__mFocusIdMutex) != 0) {
+ THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_unlock() - FocusId Mutex");
+ }
+#ifdef _AUDIO_IO_DEBUG_TIMING_
+ AUDIO_IO_LOGD(COLOR_GREEN "UNLOCK - FocusId Mutex" COLOR_END);
+#endif
+}
+
void CAudioSessionHandler::__lockFocusCBMutex() {
if (pthread_mutex_lock(&__mFocusCBMutex) != 0) {
- THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock()");
+ THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_lock() - FocusCB Mutex");
}
#ifdef _AUDIO_IO_DEBUG_TIMING_
AUDIO_IO_LOGD(COLOR_RED "LOCK - FocusCB Mutex" COLOR_END);
void CAudioSessionHandler::__unlockFocusCBMutex() {
if (pthread_mutex_unlock(&__mFocusCBMutex) != 0) {
- THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_unlock()");
+ THROW_ERROR_MSG(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed pthread_mutex_unlock() - FocusCB Mutex");
}
#ifdef _AUDIO_IO_DEBUG_TIMING_
AUDIO_IO_LOGD(COLOR_GREEN "UNLOCK - FocusCB Mutex" COLOR_END);
__mAcquiredFocus(FOCUS_NONE),
__mReasonForChange(NULL),
__mAdditionalInfo(NULL),
+ __mFocusIdMutex(PTHREAD_MUTEX_INITIALIZER),
__mFocusCBMutex(PTHREAD_MUTEX_INITIALIZER) {
__mAudioInfo = audioInfo;
}
return false;
}
+bool CAudioSessionHandler::__checkNeedBlock(const char *focus_acquired_by) {
+ assert(focus_acquired_by != NULL);
+
+ if (!strcmp(focus_acquired_by, "alarm") ||
+ !strcmp(focus_acquired_by, "ringtone-voip") ||
+ !strcmp(focus_acquired_by, "ringtone-call") ||
+ !strcmp(focus_acquired_by, "voip") ||
+ !strcmp(focus_acquired_by, "call-voice") ||
+ !strcmp(focus_acquired_by, "call-video")) {
+ AUDIO_IO_LOGW("Blocked by session policy, focus_acquired_by[%s]", focus_acquired_by);
+ return true;
+ }
+
+ return false;
+}
+
int CAudioSessionHandler::getId() {
return __mId;
}
}
if (__mUseFocus == true) {
+ __lockFocusIdMutex();
if (__mId >= 0) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_POLICY_BLOCKED, "Already registered [id:%d]", __mId);
}
CAudioError err = __convertStreamType(__mAudioSession, __mMultimediaSession, &index);
if (err != CAudioError::EError::ERROR_NONE) {
+ __unlockFocusIdMutex();
throw err;
}
errorCode = mm_sound_focus_get_id(&__mId);
if (errorCode != MM_ERROR_NONE) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_focus_get_id() err:0x%x", errorCode);
}
__sound_pcm_focus_cb,
static_cast<void*>(this));
if (errorCode != MM_ERROR_NONE) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_register_focus_for_session() err:0x%x", errorCode);
}
if (__isFocusDisableReacquisitionRequired(__mMultimediaSession, __mOptions)) {
errorCode = mm_sound_set_focus_reacquisition_for_session(__mId, false);
if (errorCode != MM_ERROR_NONE) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_set_focus_reacquisition() err:0x%x", errorCode);
}
}
// Register focus watch callback
errorCode = mm_sound_set_focus_watch_callback_for_session(getpid(), FOCUS_FOR_BOTH, __sound_pcm_focus_watch_cb, static_cast<void*>(this), &__mId);
if (errorCode < 0) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_set_focus_watch_callback_for_session() err:0x%x", errorCode);
}
AUDIO_IO_LOGD("Focus watch callback registered successfully [id:%d]", __mId);
}
+ __unlockFocusIdMutex();
}
}
THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
}
+ __lockFocusIdMutex();
if (__mUseFocus == true && __mId >= 0) {
int errorCode = 0;
// Unregister focus callback
errorCode = mm_sound_unregister_focus(__mId);
if (errorCode != MM_ERROR_NONE) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_unregister_focus() err:0x%x", errorCode);
}
// Unregister focus watch callback.
errorCode = mm_sound_unset_focus_watch_callback(__mId);
if (errorCode < 0) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_unset_focus_watch_callback() err:0x%x", errorCode);
}
}
__mAcquiredFocus = FOCUS_NONE;
}
+ __unlockFocusIdMutex();
}
void CAudioSessionHandler::updatePlaying() {
if (__mIsInit == false) {
THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Doesn't initialize CAudioSessionHandler");
}
+ __lockFocusIdMutex();
+ if (!__mUseFocus || __mId < 0) {
+ __unlockFocusIdMutex();
+ return;
+ }
if (__mUseFocus && __isFocusRequired(__mMultimediaSession, __mOptions)) {
if (__mId >= 0) {
int focus_type = 0;
bool is_focus_cb_thread;
- if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+ if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread))) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed mm_sound_focus_is_cb_thread() err:0x%x", ret);
+ }
if (!is_focus_cb_thread)
__lockFocusCBMutex();
AUDIO_IO_LOGW("Focus was already acquired, skip it...");
if (!is_focus_cb_thread)
__unlockFocusCBMutex();
+ __unlockFocusIdMutex();
return;
}
if (ret != MM_ERROR_NONE) {
if (!is_focus_cb_thread)
__unlockFocusCBMutex();
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_POLICY_BLOCKED, "Failed mm_sound_acquire_focus() err:0x%x", ret);
}
__mAcquiredFocus = FOCUS_FOR_BOTH;
if (!is_focus_cb_thread)
__unlockFocusCBMutex();
}
+ } else {
+ int ret = MM_ERROR_NONE;
+ char *stream_type = NULL;
+ char *ext_info = NULL;
+ int option = 0;
+
+ if ((ret = mm_sound_get_stream_type_of_acquired_focus(FOCUS_FOR_BOTH, &stream_type, &option, &ext_info))) {
+ __unlockFocusIdMutex();
+ return;
+ }
+
+ AUDIO_IO_LOGD("Focus is acquired by stream_type[%s], option[%d], ext_info[%s]", stream_type, option, ext_info);
+
+ if (__checkNeedBlock((const char*)stream_type)) {
+ free(stream_type);
+ free(ext_info);
+ __unlockFocusIdMutex();
+ THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_POLICY_BLOCKED, "Blocked by an acquired focus");
+ }
+ free(stream_type);
+ free(ext_info);
}
+ __unlockFocusIdMutex();
}
void CAudioSessionHandler::updateStop() {
}
if (__mUseFocus && __isFocusRequired(__mMultimediaSession, __mOptions)) {
+ __lockFocusIdMutex();
if (__mId >= 0) {
int ret = MM_ERROR_NONE;
bool is_focus_cb_thread;
- if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread)))
+ if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread))) {
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, "Failed mm_sound_focus_is_cb_thread() err:0x%x", ret);
+ }
if (!is_focus_cb_thread)
__lockFocusCBMutex();
AUDIO_IO_LOGW("Focus was already released, skip it...");
if (!is_focus_cb_thread)
__unlockFocusCBMutex();
+ __unlockFocusIdMutex();
return;
}
if (ret != MM_ERROR_NONE) {
if (!is_focus_cb_thread)
__unlockFocusCBMutex();
+ __unlockFocusIdMutex();
THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed mm_sound_release_focus() err:0x%x", ret);
}
__mAcquiredFocus = FOCUS_NONE;
if (!is_focus_cb_thread)
__unlockFocusCBMutex();
}
+ __unlockFocusIdMutex();
}
}