From: Sangchul Lee Date: Fri, 16 Jun 2017 00:56:04 +0000 (+0900) Subject: Add new API to deliver focus to another stream info handle without invoking focus... X-Git-Tag: submit/tizen/20170626.070954~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F04%2F134304%2F6;p=platform%2Fcore%2Fapi%2Fsound-manager.git Add new API to deliver focus to another stream info handle without invoking focus(watch) state changed callback [Version] 0.4.13 [Issue Type] New feature Change-Id: If2422f28fd1148fd2885fde160efa1e38cabdff8 Signed-off-by: Sangchul Lee --- diff --git a/include/sound_manager.h b/include/sound_manager.h index 01c4699..db6fa95 100644 --- a/include/sound_manager.h +++ b/include/sound_manager.h @@ -946,6 +946,33 @@ int sound_manager_set_focus_reacquisition(sound_stream_info_h stream_info, bool */ int sound_manager_get_focus_reacquisition(sound_stream_info_h stream_info, bool *enabled); +/** + * @brief Delivers focuses to another stream information. + * @since_tizen 4.0 + * + * @remarks This function does not affect any invocation of sound_stream_focus_state_changed_cb() or\n + * sound_stream_focus_state_watch_cb(). Do not call this function within sound_stream_focus_state_changed_cb() or\n + * sound_stream_focus_state_watch_cb(), otherwise #SOUND_MANAGER_ERROR_INVALID_OPERATION will be returned. + * + * @param[in] source The source handle of stream information which has focuses + * @param[in] destination The destination handle of stream information which will receive focuses + * @param[in] focus_mask The focus mask to deliver + * @return @c 0 on success, + * otherwise a negative error value + * @retval #SOUND_MANAGER_ERROR_NONE Success + * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation + * @retval #SOUND_MANAGER_ERROR_INVALID_STATE Invalid state + * @retval #SOUND_MANAGER_ERROR_POLICY Noncompliance with the sound system policy + * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system + * @pre Call sound_manager_create_stream_information(), sound_manager_acquire_focus() and sound_manager_acquire_focus_all()\n + * before calling this function. + * @see sound_manager_create_stream_information() + * @see sound_manager_acquire_focus() + * @see sound_manager_acquire_focus_all() + */ +int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask); + /** * @brief Checks if the stream information is using the device. * @since_tizen 3.0 diff --git a/packaging/capi-media-sound-manager.spec b/packaging/capi-media-sound-manager.spec index 192aeee..2943b97 100644 --- a/packaging/capi-media-sound-manager.spec +++ b/packaging/capi-media-sound-manager.spec @@ -1,6 +1,6 @@ Name: capi-media-sound-manager Summary: Sound Manager library -Version: 0.4.12 +Version: 0.4.13 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/sound_manager.c b/src/sound_manager.c index 5007106..13e7277 100644 --- a/src/sound_manager.c +++ b/src/sound_manager.c @@ -586,6 +586,59 @@ int sound_manager_get_focus_state(sound_stream_info_h stream_info, sound_stream_ return _convert_sound_manager_error_code(__func__, ret); } +int sound_manager_deliver_focus(sound_stream_info_h source, sound_stream_info_h destination, sound_stream_focus_mask_e focus_mask) +{ + int ret = MM_ERROR_NONE; + sound_stream_info_s *src_stream_h = (sound_stream_info_s*)source; + sound_stream_info_s *dst_stream_h = (sound_stream_info_s*)destination; + bool is_focus_cb_thread = false; + + LOGI(">> enter"); + + SM_INSTANCE_CHECK(src_stream_h); + SM_INSTANCE_CHECK(dst_stream_h); + + if ((ret = mm_sound_focus_is_cb_thread(&is_focus_cb_thread))) + return _convert_sound_manager_error_code(__func__, ret); + + if (is_focus_cb_thread) { + LOGE("not allowed calling this function in focus(watch) callback"); + return SOUND_MANAGER_ERROR_INVALID_OPERATION; + } + + if (src_stream_h->index == dst_stream_h->index) { + LOGE("not allowed because both handles have same index(%u)", src_stream_h->index); + return SOUND_MANAGER_ERROR_INVALID_PARAMETER; + } + + if (src_stream_h->is_focus_unavailable || dst_stream_h->is_focus_unavailable) { + LOGE("focus is unavailable for source(%d)/destination(%d)", + src_stream_h->is_focus_unavailable, dst_stream_h->is_focus_unavailable); + return SOUND_MANAGER_ERROR_POLICY; + } + + if (!(src_stream_h->acquired_focus & focus_mask) || (src_stream_h->acquired_focus < focus_mask)) { + LOGE("could not deliver the request focus(0x%x), current acquired focus(0x%x)", + focus_mask, src_stream_h->acquired_focus); + return SOUND_MANAGER_ERROR_INVALID_STATE; + } + + if (dst_stream_h->user_cb == NULL) { + LOGE("focus state changed callback should be set to destination handle"); + return SOUND_MANAGER_ERROR_POLICY; + } + + ret = mm_sound_deliver_focus(src_stream_h->index, dst_stream_h->index, (mm_sound_focus_type_e)focus_mask); + if (ret == MM_ERROR_NONE) { + src_stream_h->acquired_focus &= ~focus_mask; + src_stream_h->prev_acquired_focus &= ~focus_mask; + dst_stream_h->acquired_focus |= focus_mask; + dst_stream_h->prev_acquired_focus |= focus_mask; + } + + return _convert_sound_manager_error_code(__func__, ret); +} + int sound_manager_is_stream_on_device(sound_stream_info_h stream_info, sound_device_h device, bool *is_on) { int ret = MM_ERROR_NONE; diff --git a/test/sound_manager_test.c b/test/sound_manager_test.c index 716c502..73c859b 100644 --- a/test/sound_manager_test.c +++ b/test/sound_manager_test.c @@ -79,6 +79,7 @@ enum { CURRENT_STATUS_RELEASE_FOCUS_ALL, CURRENT_STATUS_GET_ACQUIRED_FOCUS, CURRENT_STATUS_GET_SOUND_TYPE, + CURRENT_STATUS_DELIVER_FOCUS, CURRENT_STATUS_DESTROY_STREAM_INFO, CURRENT_STATUS_ADD_FOCUS_WATCH_CB, CURRENT_STATUS_REMOVE_FOCUS_WATCH_CB, @@ -251,6 +252,8 @@ void _interpret_main_menu(char *cmd) g_menu_state = CURRENT_STATUS_GET_ACQUIRED_FOCUS; else if (strncmp(cmd, "gst", 3) == 0) g_menu_state = CURRENT_STATUS_GET_SOUND_TYPE; + else if (strncmp(cmd, "dfc", 3) == 0) + g_menu_state = CURRENT_STATUS_DELIVER_FOCUS; else if (strncmp(cmd, "afw", 3) == 0) g_menu_state = CURRENT_STATUS_ADD_FOCUS_WATCH_CB; else if (strncmp(cmd, "rfw", 3) == 0) @@ -358,7 +361,8 @@ void display_sub_basic() g_print("rfc. Release Focus\t"); g_print("gfs. Get Focus State\n"); g_print("afa. Acquire Focus All\t"); - g_print("rfa. Release Focus All\n"); + g_print("rfa. Release Focus All\t"); + g_print("dfc. Deliver Focus\n"); g_print("afw. Add Focus State Watch CB\t"); g_print("rfw. Remove Focus State Watch CB\n"); g_print("sfr. Set Focus Reacquisition\t"); @@ -479,6 +483,8 @@ static void displaymenu() g_print("*** input behavior for acquire all (0:without behavior, 1:with noResume, 2:with fading)\n"); else if (g_menu_state == CURRENT_STATUS_RELEASE_FOCUS_ALL) g_print("*** input behavior for release all (0:without behavior, 1:with noResume, 2:with fading)\n"); + else if (g_menu_state == CURRENT_STATUS_DELIVER_FOCUS) + g_print("*** input focus type to deliver (0:playback, 1:recording, 2:both)\n"); else if (g_menu_state == CURRENT_STATUS_GET_ACQUIRED_FOCUS) g_print("*** press enter to get focus state\n"); else if (g_menu_state == CURRENT_STATUS_GET_SOUND_TYPE) @@ -1710,6 +1716,43 @@ static void interpret(char *cmd) reset_menu_state(); break; } + case CURRENT_STATUS_DELIVER_FOCUS: { + int ret = SOUND_MANAGER_ERROR_NONE; + sound_stream_focus_mask_e focus_mask; + sound_stream_info_h stream_info_h = NULL; + int focus_type = atoi(cmd); + + ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, focus_callback, NULL, &stream_info_h); + if (ret) { + g_print("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret); + reset_menu_state(); + break; + } + + switch (focus_type) { + case 0: /* playback */ + focus_mask = SOUND_STREAM_FOCUS_FOR_PLAYBACK; + break; + case 1: /* recording */ + focus_mask = SOUND_STREAM_FOCUS_FOR_RECORDING; + break; + case 2: /* both */ + focus_mask = SOUND_STREAM_FOCUS_FOR_BOTH; + break; + default: + g_print("invalid selection(%d), keep going with PLAYBACK focus..\n", focus_type); + focus_mask = SOUND_STREAM_FOCUS_FOR_PLAYBACK; + break; + } + ret = sound_manager_deliver_focus(g_stream_info_h, stream_info_h, focus_mask); + if (ret) + g_print("fail to sound_manager_deliver_focus(), ret(0x%x)\n", ret); + + sound_manager_destroy_stream_information(stream_info_h); + + reset_menu_state(); + break; + } case CURRENT_STATUS_GET_ACQUIRED_FOCUS: { sound_stream_focus_state_e for_playback; sound_stream_focus_state_e for_recording;