[0.6.35] update internal focus status right after acquring/releasing focus
[platform/core/multimedia/libmm-player.git] / src / mm_player_sound_focus.c
index 88eed87..d38414c 100644 (file)
 #include "mm_player_sound_focus.h"
 
 #define MMPLAYER_CHECK_SOUND_FOCUS_INSTANCE(x_player_sound_focus) \
-do \
-{ \
-       if (!x_player_sound_focus) \
-       { \
+do { \
+       if (!x_player_sound_focus) { \
                LOGD("no sound focus instance");\
                return MM_ERROR_SOUND_NOT_INITIALIZED; \
        } \
-}while(0);
+} while (0);
 
-void __mmplayer_sound_signal_callback (mm_sound_signal_name_t signal, int value, void *user_data)
+void __mmplayer_sound_signal_callback(mm_sound_signal_name_t signal, int value, void *user_data)
 {
        MMPlayerSoundFocus *sound_focus = (MMPlayerSoundFocus*)user_data;
-       int ret = MM_ERROR_NONE;
+       MMPLAYER_RETURN_IF_FAIL(sound_focus);
 
        LOGD("sound signal callback %d / %d", signal, value);
 
-       if (signal == MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS)
-       {
-               if (value == 1)
-               {
-                       /* unregister watch callback */
-                       if (sound_focus->watch_id > 0)
-                       {
-                               LOGD("unset the focus watch cb %d", sound_focus->watch_id);
-
-                               ret = mm_sound_unset_focus_watch_callback(sound_focus->watch_id);
-                               sound_focus->watch_id = 0;
-                               if (ret != MM_ERROR_NONE)
-                                       LOGE("failed to mm_sound_unset_focus_watch_callback()");
-                               /*
-                               if (sound_focus->subscribe_id > 0)
-                                       mm_sound_unsubscribe_signal(sound_focus->subscribe_id);
-                               */
-                       }
-                       /* unregister focus callback */
-                       if (sound_focus->focus_id > 0)
-                       {
-                               ret = mm_sound_unregister_focus(sound_focus->focus_id);
-                               sound_focus->focus_id = 0;
-                               if (ret != MM_ERROR_NONE)
-                                       LOGE("failed to mm_sound_unregister_focus() %d", sound_focus->focus_id);
-                       }
-                       /* unregister device connected callback */
-                       if (sound_focus->connected_id > 0)
-                       {
-                               LOGD("unset the device connected cb %d", sound_focus->connected_id);
-                               ret = mm_sound_remove_device_connected_callback(sound_focus->connected_id);
-                               sound_focus->connected_id = 0;
-                               if (ret != MM_ERROR_NONE)
-                                       LOGE("failed to mm_sound_remove_device_connected_callback()");
-                       }
-               }
-       }
+       if (signal == MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS && value == 1)
+               _mmplayer_sound_unregister(sound_focus);
 }
 
 static void
 __mmplayer_sound_device_connected_cb_func(MMSoundDevice_t device_h, bool is_connected, void *user_data)
 {
        mm_player_t* player = (mm_player_t*) user_data;
-       MMPLAYER_RETURN_IF_FAIL( player );
+       MMPLAYER_RETURN_IF_FAIL(player);
 
        mm_sound_device_type_e device_type;
        int ret;
-       MMMessageParamType msg = {0, };
 
        LOGW("device_connected_cb is called, device_h[0x%x], is_connected[%d]\n", device_h, is_connected);
 
@@ -102,30 +64,31 @@ __mmplayer_sound_device_connected_cb_func(MMSoundDevice_t device_h, bool is_conn
        ret = mm_sound_get_device_type(device_h, &device_type);
 
        if (!is_connected && MMPLAYER_CURRENT_STATE(player) == MM_PLAYER_STATE_PLAYING
-               && (player->sound_focus.focus_id > 0 || player->sound_focus.watch_id > 0))
-       {
-               switch (device_type)
+               && (player->sound_focus.focus_id > 0 || player->sound_focus.watch_id > 0)) {
+               switch (device_type) {
+               case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
+               case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
+               case MM_SOUND_DEVICE_TYPE_HDMI:
+               case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
                {
-                       case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
-                       case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
-                       case MM_SOUND_DEVICE_TYPE_HDMI:
-                       case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
-                       {
-                               ret = gst_element_set_state(player->pipeline->mainbin[MMPLAYER_M_PIPE].gst, GST_STATE_PAUSED);
-                               if (ret != GST_STATE_CHANGE_SUCCESS)
-                               {
-                                       LOGE("focus_id [%d], watch_id [%d], connected_id [%d], change_state result[%d]",
-                                               player->sound_focus.focus_id, player->sound_focus.watch_id,
-                                               player->sound_focus.connected_id, ret);
-                               }
-                               msg.union_type = MM_MSG_UNION_CODE;
-                               msg.code = MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG;
-                               MMPLAYER_POST_MSG( player, MM_MESSAGE_STATE_INTERRUPTED, &msg );
+                       int result = MM_ERROR_NONE;
+                       LOGW("pause immediately");
+
+                       player->sound_focus.by_asm_cb = TRUE;
+                       player->sound_focus.focus_changed_msg = MM_PLAYER_FOCUS_CHANGED_BY_EARJACK_UNPLUG;
+
+                       result = _mmplayer_pause((MMHandleType)player);
+                       if (result != MM_ERROR_NONE) {
+                               LOGE("focus_id [%d], watch_id [%d], connected_id [%d], change_state result[%d]",
+                                       player->sound_focus.focus_id, player->sound_focus.watch_id,
+                                       player->sound_focus.connected_id, ret);
                        }
-                       break;
+                       player->sound_focus.by_asm_cb = FALSE;
+               }
+               break;
 
-                       default:
-                               LOGD("do nothing");
+               default:
+                       LOGD("do nothing");
                }
        }
 }
@@ -133,23 +96,22 @@ __mmplayer_sound_device_connected_cb_func(MMSoundDevice_t device_h, bool is_conn
 const gchar *
 __mmplayer_sound_get_stream_type(gint type)
 {
-       switch ( type )
-       {
-               case MM_SESSION_TYPE_CALL:
-               case MM_SESSION_TYPE_VIDEOCALL:
-               case MM_SESSION_TYPE_VOIP:
-                       return "ringtone-voip";
-               case MM_SESSION_TYPE_MEDIA:
-                       return "media";
-               case MM_SESSION_TYPE_NOTIFY:
-                       return "notification";
-               case MM_SESSION_TYPE_ALARM:
-                       return "alarm";
-               case MM_SESSION_TYPE_EMERGENCY:
-                       return "emergency";
-               default:
-                       LOGW("unexpected case!\n");
-                       return "media";
+       switch (type) {
+       case MM_SESSION_TYPE_CALL:
+       case MM_SESSION_TYPE_VIDEOCALL:
+       case MM_SESSION_TYPE_VOIP:
+               return "ringtone-voip";
+       case MM_SESSION_TYPE_MEDIA:
+               return "media";
+       case MM_SESSION_TYPE_NOTIFY:
+               return "notification";
+       case MM_SESSION_TYPE_ALARM:
+               return "alarm";
+       case MM_SESSION_TYPE_EMERGENCY:
+               return "emergency";
+       default:
+               LOGW("unexpected case!\n");
+               return "media";
        }
 
        return "media";
@@ -159,31 +121,28 @@ int
 _mmplayer_sound_acquire_focus(MMPlayerSoundFocus* sound_focus)
 {
        int ret = MM_ERROR_NONE;
-       const gchar *stream_type = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_CHECK_SOUND_FOCUS_INSTANCE(sound_focus);
 
-       if (sound_focus->acquired)
-       {
+       if (sound_focus->acquired) {
                LOGW("focus is already acquired. can't acquire again.");
                return MM_ERROR_NONE;
        }
 
-       stream_type = __mmplayer_sound_get_stream_type(sound_focus->session_type);
-
-       if ((!strstr(stream_type, "media")) ||
-               (sound_focus->session_flags & MM_SESSION_OPTION_PAUSE_OTHERS))
-       {
+       if (_mmplayer_is_using_internal_sound_focus(sound_focus)) {
 
                ret = mm_sound_acquire_focus(sound_focus->focus_id, FOCUS_FOR_BOTH, NULL);
-               if (ret != MM_ERROR_NONE)
-               {
+               if (ret != MM_ERROR_NONE) {
                        LOGE("failed to acquire sound focus\n");
                        return ret;
                }
 
                sound_focus->acquired = TRUE;
+
+               ret = mm_sound_update_focus_status(sound_focus->focus_id, 1);
+               if (ret != MM_ERROR_NONE)
+                       LOGE("failed to update focus status\n");
        }
 
        MMPLAYER_FLEAVE();
@@ -194,30 +153,27 @@ int
 _mmplayer_sound_release_focus(MMPlayerSoundFocus* sound_focus)
 {
        int ret = MM_ERROR_NONE;
-       const gchar *stream_type = NULL;
 
        MMPLAYER_FENTER();
        MMPLAYER_CHECK_SOUND_FOCUS_INSTANCE(sound_focus);
 
-       if (!sound_focus->acquired)
-       {
+       if (!sound_focus->acquired) {
                LOGW("focus is not acquired. no need to release.");
                return MM_ERROR_NONE;
        }
 
-       stream_type = __mmplayer_sound_get_stream_type(sound_focus->session_type);
-
-       if ((!strstr(stream_type, "media")) ||
-               (sound_focus->session_flags & MM_SESSION_OPTION_PAUSE_OTHERS))
-       {
+       if (_mmplayer_is_using_internal_sound_focus(sound_focus)) {
                ret = mm_sound_release_focus(sound_focus->focus_id, FOCUS_FOR_BOTH, NULL);
-               if (ret != MM_ERROR_NONE)
-               {
+               if (ret != MM_ERROR_NONE) {
                        LOGE("failed to release sound focus\n");
                        return ret;
                }
 
                sound_focus->acquired = FALSE;
+
+               ret = mm_sound_update_focus_status(sound_focus->focus_id, 0);
+               if (ret != MM_ERROR_NONE)
+                       LOGE("failed to update focus status\n");
        }
 
        MMPLAYER_FLEAVE();
@@ -231,9 +187,11 @@ _mmplayer_sound_register(MMPlayerSoundFocus* sound_focus,
        gint pid = -1;
        gint ret = MM_ERROR_NONE;
        const gchar *stream_type = NULL;
+       mm_player_t* player = MM_PLAYER_CAST(param);
 
        MMPLAYER_FENTER();
        MMPLAYER_CHECK_SOUND_FOCUS_INSTANCE(sound_focus);
+       MMPLAYER_RETURN_VAL_IF_FAIL(player, MM_ERROR_INVALID_ARGUMENT);
 
        /* check if it's running on the media_server */
        if (sound_focus->pid > 0)
@@ -246,17 +204,14 @@ _mmplayer_sound_register(MMPlayerSoundFocus* sound_focus,
        ret = _mm_session_util_read_information(pid, &sound_focus->session_type, &sound_focus->session_flags);
        LOGW("Read Session Type -> ret:0x%X \n", ret);
 
-       /* case 1. if there is no session */
-       if (ret == MM_ERROR_INVALID_HANDLE)
-       {
+       if (ret == MM_ERROR_INVALID_HANDLE) {
+               /* case 1. if there is no session */
                LOGW("subscribe_id=%d\n", sound_focus->subscribe_id);
 
-               if (sound_focus->subscribe_id == 0)
-               {
+               if (sound_focus->subscribe_id == 0) {
                        ret = mm_sound_subscribe_signal_for_daemon(MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS, pid, &sound_focus->subscribe_id,
                                                                        (mm_sound_signal_callback)__mmplayer_sound_signal_callback, (void*)sound_focus);
-                       if (ret != MM_ERROR_NONE)
-                       {
+                       if (ret != MM_ERROR_NONE) {
                                LOGE("mm_sound_subscribe_signal is failed\n");
                                return MM_ERROR_POLICY_BLOCKED;
                        }
@@ -265,45 +220,36 @@ _mmplayer_sound_register(MMPlayerSoundFocus* sound_focus,
                        /* register watch callback */
                        ret = mm_sound_set_focus_watch_callback_for_session(pid ,
                                        FOCUS_FOR_BOTH, watch_cb, (void*)param, &sound_focus->watch_id);
-                       if (ret != MM_ERROR_NONE)
-                       {
+                       if (ret != MM_ERROR_NONE) {
                                LOGE("mm_sound_set_focus_watch_callback is failed\n");
                                return MM_ERROR_POLICY_BLOCKED;
                        }
                        /* register device connected callback */
                        ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
                                        (mm_sound_device_connected_cb)__mmplayer_sound_device_connected_cb_func, (void*)param, &sound_focus->connected_id);
-                       if (ret != MM_ERROR_NONE)
-                       {
+                       if (ret != MM_ERROR_NONE) {
                                LOGE("mm_sound_add_device_connected_callback is failed\n");
                                return MM_ERROR_POLICY_BLOCKED;
                        }
                        LOGD("register device connected callback for the value is 0, sub_cb id %d\n", sound_focus->connected_id);
                }
                ret = MM_ERROR_NONE;
-       }
-       /* case 2. if sessoin exists */
-       else if (ret == MM_ERROR_NONE)
-       {
+       } else if (ret == MM_ERROR_NONE) {
+               /* case 2. if sessoin exists */
                /* in this case, this process is using stream info created by using sound-manager,
                 * we're going to skip working on backward compatibility of session. */
-               if (sound_focus->session_type == MM_SESSION_TYPE_REPLACED_BY_STREAM)
-               {
+               if (sound_focus->session_type == MM_SESSION_TYPE_REPLACED_BY_STREAM) {
                        LOGW("this process is using stream info. skip it..");
-               }
-               else
-               {
+               } else {
                        /* interpret session information */
                        stream_type = __mmplayer_sound_get_stream_type(sound_focus->session_type);
                        LOGD("fid [%d] wid [%d] type[%s], flags[0x%02X]\n",
                                sound_focus->focus_id, sound_focus->watch_id, stream_type, sound_focus->session_flags);
 
-                       if (sound_focus->focus_id == 0)
-                       {
+                       if (sound_focus->focus_id == 0) {
                                /* get unique id */
                                ret = mm_sound_focus_get_id(&sound_focus->focus_id);
-                               if (ret != MM_ERROR_NONE)
-                               {
+                               if (ret != MM_ERROR_NONE) {
                                        LOGE("failed to get unique focus id\n");
                                        return MM_ERROR_POLICY_BLOCKED;
                                }
@@ -311,8 +257,7 @@ _mmplayer_sound_register(MMPlayerSoundFocus* sound_focus,
                                /* register sound focus callback */
                                ret = mm_sound_register_focus_for_session(sound_focus->focus_id, pid,
                                                stream_type, focus_cb, (void*)param);
-                               if (ret != MM_ERROR_NONE)
-                               {
+                               if (ret != MM_ERROR_NONE) {
                                        LOGE("mm_sound_register_focus is failed\n");
                                        return MM_ERROR_POLICY_BLOCKED;
                                }
@@ -321,36 +266,36 @@ _mmplayer_sound_register(MMPlayerSoundFocus* sound_focus,
                        if ((sound_focus->watch_id == 0) &&
                                (strstr(stream_type, "media")) &&
                                !(sound_focus->session_flags & MM_SESSION_OPTION_PAUSE_OTHERS) &&
-                               !(sound_focus->session_flags & MM_SESSION_OPTION_UNINTERRUPTIBLE))
-                       {
+                               !(sound_focus->session_flags & MM_SESSION_OPTION_UNINTERRUPTIBLE)) {
                                LOGD("register focus watch callback\n");
                                /* register watch callback */
                                ret = mm_sound_set_focus_watch_callback_for_session(pid,
                                                FOCUS_FOR_BOTH, watch_cb, (void*)param, &sound_focus->watch_id);
-                               if (ret != MM_ERROR_NONE)
-                               {
+                               if (ret != MM_ERROR_NONE) {
                                        LOGE("mm_sound_set_focus_watch_callback is failed\n");
                                        return MM_ERROR_POLICY_BLOCKED;
                                }
                        }
 
-                       if(sound_focus->connected_id == 0)
-                       {
+                       if ((strstr(stream_type, "media")) && (sound_focus->connected_id == 0)) {
                                /* register device connected callback */
                                ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
                                                (mm_sound_device_connected_cb)__mmplayer_sound_device_connected_cb_func, (void*)param, &sound_focus->connected_id);
-                               if (ret != MM_ERROR_NONE)
-                               {
+                               if (ret != MM_ERROR_NONE) {
                                        LOGE("mm_sound_add_device_connected_callback is failed\n");
                                        return MM_ERROR_POLICY_BLOCKED;
                                }
                                LOGD("register device connected callback for the value is 0, sub_cb id %d\n", sound_focus->connected_id);
                        }
+
+                       ret = mm_player_set_attribute(player, NULL, "sound_stream_type", stream_type, strlen(stream_type), (char *)NULL);
+                       if (ret != MM_ERROR_NONE) {
+                               LOGE("mm_player_set_attribute for sound_stream_type is failed\n");
+                               return ret;
+                       }
                }
                ret = MM_ERROR_NONE;
-       }
-       else
-       {
+       } else {
                LOGE("_mm_session_util_read_information is failed");
                ret =  MM_ERROR_POLICY_BLOCKED;
        }
@@ -370,31 +315,27 @@ _mmplayer_sound_unregister(MMPlayerSoundFocus* sound_focus)
 
        LOGD("unregister sound focus callback\n");
 
-       if (sound_focus->focus_id > 0)
-       {
+       if (sound_focus->focus_id > 0) {
                ret = mm_sound_unregister_focus(sound_focus->focus_id);
-               if(ret != MM_ERROR_NONE)
+               if (ret != MM_ERROR_NONE)
                        LOGE("failed to mm_sound_unregister_focus() %d", sound_focus->focus_id);
                sound_focus->focus_id = 0;
        }
 
-       if (sound_focus->watch_id > 0)
-       {
+       if (sound_focus->watch_id > 0) {
                ret = mm_sound_unset_focus_watch_callback(sound_focus->watch_id);
-               if(ret != MM_ERROR_NONE)
+               if (ret != MM_ERROR_NONE)
                        LOGE("failed to mm_sound_unset_focus_watch_callback() %d", sound_focus->watch_id);
                sound_focus->watch_id = 0;
        }
 
-       if (sound_focus->subscribe_id > 0)
-       {
+       if (sound_focus->subscribe_id > 0) {
                mm_sound_unsubscribe_signal(sound_focus->subscribe_id);
                sound_focus->subscribe_id = 0;
        }
-       if( sound_focus->connected_id > 0 )
-       {
+       if (sound_focus->connected_id > 0) {
                ret = mm_sound_remove_device_connected_callback(sound_focus->connected_id);
-               if(ret != MM_ERROR_NONE)
+               if (ret != MM_ERROR_NONE)
                        LOGE("failed to mm_sound_remove_device_connected_callback() %d", sound_focus->connected_id);
                sound_focus->connected_id = 0;
        }
@@ -404,3 +345,19 @@ _mmplayer_sound_unregister(MMPlayerSoundFocus* sound_focus)
        return MM_ERROR_NONE;
 }
 
+bool _mmplayer_is_using_internal_sound_focus(MMPlayerSoundFocus* sound_focus)
+{
+       MMPLAYER_RETURN_VAL_IF_FAIL(sound_focus, false);
+
+       /* Perhaps, already got release signal or application may use stream focus directly */
+       if (sound_focus->focus_id == 0)
+               return false;
+
+       if ((sound_focus->session_type == MM_SESSION_TYPE_MEDIA && sound_focus->session_flags & MM_SESSION_OPTION_PAUSE_OTHERS) ||
+               (sound_focus->session_type == MM_SESSION_TYPE_NOTIFY) ||
+               (sound_focus->session_type == MM_SESSION_TYPE_ALARM) ||
+               (sound_focus->session_type == MM_SESSION_TYPE_EMERGENCY))
+               return true;
+       else
+               return false;
+}