Add new API to deliver focus to another stream info handle without invoking focus... 04/134304/6
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 16 Jun 2017 00:56:04 +0000 (09:56 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 22 Jun 2017 01:00:55 +0000 (10:00 +0900)
[Version] 0.4.13
[Issue Type] New feature

Change-Id: If2422f28fd1148fd2885fde160efa1e38cabdff8
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/sound_manager.h
packaging/capi-media-sound-manager.spec
src/sound_manager.c
test/sound_manager_test.c

index 01c4699..db6fa95 100644 (file)
@@ -947,6 +947,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
  *
index 192aeee..2943b97 100644 (file)
@@ -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
index 5007106..13e7277 100644 (file)
@@ -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;
index 716c502..73c859b 100644 (file)
@@ -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;