[ACR-1199]Add APIs for playling designated playlist item. 16/174816/7 accepted/tizen/unified/20180411.065620 submit/tizen/20180411.022759
authorhj kim <backto.kim@samsung.com>
Wed, 4 Apr 2018 09:15:51 +0000 (18:15 +0900)
committerhj kim <backto.kim@samsung.com>
Fri, 6 Apr 2018 05:22:39 +0000 (05:22 +0000)
Change-Id: I7192d1468ae4e24a00a51adebd17492759a03893

include/media_controller_client.h
include/media_controller_private.h
include/media_controller_server.h
src/media_controller_client.c
src/media_controller_server.c
src/media_controller_util.c
test/client_test/media_controller_client_test.c
test/server_test/media_controller_server_test.c

index 6f4552f..8146a15 100755 (executable)
@@ -831,7 +831,7 @@ int mc_client_send_playback_action(mc_client_h client, const char *server_name,
  *
  * @param[in] client    The handle to the media controller client
  * @param[in] server_name    The app_id of the media controller server
- * @param[in] position   The playback position to send to media controller server
+ * @param[in] position   The position of the playback in milliseconds to send to media controller server.
  * @return @c 0 on success,
  *         otherwise a negative error value
  * @retval #MEDIA_CONTROLLER_ERROR_NONE Successful
@@ -910,6 +910,30 @@ int mc_client_send_repeat_mode_command(mc_client_h client, const char *server_na
 int mc_client_send_custom_command(mc_client_h client, const char *server_name, const char *command, bundle *data, mc_command_reply_received_cb callback, void *user_data);
 
 /**
+ * @brief Sends the playlist command to server.
+ * @details The media controller client can send "item id" of the playlist to the media controller server with playback action and position.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @param[in] client    The handle to the media controller client
+ * @param[in] server_name    The app_id of the media controller server
+ * @param[in] playlist_name    The playlist name of the server
+ * @param[in] media_id    The ID of the media in playlist to send to the media controller server
+ * @param[in] action    The playback action command to send to the media controller server
+ * @param[in] position    The position of the playback in milliseconds to send to media controller server
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_CONTROLLER_ERROR_NONE Successful
+ * @retval #MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller client handle by calling mc_client_create().
+ * @see mc_client_create()
+ */
+int mc_client_send_playlist_command(mc_client_h client, const char *server_name, const char *playlist_name, const char *media_id, mc_playback_action_e action, unsigned long long position);
+
+/**
  * @brief Destroys client.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
  * @param[in] client The handle to the media controller client
index 1de3966..8f78787 100755 (executable)
@@ -156,6 +156,8 @@ extern "C" {
 #define MC_DBUS_SIGNAL_NAME_CUSTOM_CMD                         "custom_cmd"
 #define MC_DBUS_SIGNAL_NAME_CMD_REPLY                          "custom_cmd_reply"
 #define MC_DBUS_SIGNAL_NAME_PLAYLIST                                   "playlist"
+#define MC_DBUS_SIGNAL_NAME_PLAYBACK_PLAYLIST          "pb_playlist"
+
 
 #define MC_COMMAND_PLAYBACKSTATE               "_pb_state_cmd_"
 #define MC_COMMAND_PLAYBACKACTION              "_pb_action_cmd_"
@@ -163,6 +165,8 @@ extern "C" {
 #define MC_COMMAND_SHUFFLE                             "_shuffle_cmd_"
 #define MC_COMMAND_REPEAT                              "_repeat_cmd_"
 #define MC_COMMAND_CUSTOM                              "_custom_cmd_"
+#define MC_COMMAND_PLAY_PLAYLIST               "_playlist_cmd_"
+
 
 #define DEFAULT_USER_UID 5001  /* owner */
 
@@ -225,6 +229,7 @@ typedef struct {
        media_controller_receiver_s shuffle_mode_reciever;
        media_controller_receiver_s repeat_mode_reciever;
        media_controller_receiver_s custom_cmd_reciever;
+       media_controller_receiver_s play_playlist_reciever;
 } media_controller_server_s;
 
 typedef struct {
@@ -262,8 +267,8 @@ typedef struct {
 int mc_util_get_own_name(char **name);
 char* mc_util_get_interface_name(const char *type, const char *name);
 int mc_util_make_filter_interface_name(const char *prefix, const char *filter, char **interface_name);
-int mc_util_set_command_availabe(const char *name, const char *command_type, const char *command);
-int mc_util_get_command_availabe(const char *name, const char *command_type, const char *command);
+int mc_util_set_command_available(const char *name, const char *command_type, const char *command);
+int mc_util_get_command_available(const char *name, const char *command_type, const char *command);
 int mc_safe_strtoi(const char *buffer, int *value);
 int mc_safe_strtoull(const char *buffer, unsigned long long *value);
 
index f993540..f6ae46a 100755 (executable)
@@ -74,7 +74,7 @@ typedef void (*mc_server_playback_action_received_cb)(const char* client_name, m
  * @remarks The callback is called in the dbus event loop.
  *
  * @param[in] client_name    The app_id of the media controller client. It can be used only in the callback. To use outside, make a copy.
- * @param[in] position    The received playback position
+ * @param[in] position    The received playback position (milliseconds)
  * @param[in] user_data        The user data passed from the mc_server_set_playback_position_command_received_cb() function
  *
  * @pre mc_server_set_playback_position_command_received_cb()
@@ -117,7 +117,7 @@ typedef void (*mc_server_repeat_mode_command_received_cb)(const char* client_nam
 
 /**
  * @brief Called when the Server receives custom command from the client.
- * @details This callback is called when server receives custom recommand from client.
+ * @details This callback is called when server receives custom command from client.
  *                If there is reply for command, call mc_server_send_command_reply() function.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
  *
@@ -135,6 +135,25 @@ typedef void (*mc_server_repeat_mode_command_received_cb)(const char* client_nam
 typedef void (*mc_server_custom_command_received_cb)(const char* client_name, const char *command, bundle *data, void *user_data);
 
 /**
+ * @brief Called when the Server receives playlist command from the client.
+ * @since_tizen 5.0
+ *
+ * @remarks The callback is called in the dbus event loop.
+ *
+ * @param[in] client_name    The app_id of the media controller client. It can be used only in the callback. To use outside, make a copy.
+ * @param[in] playlist_name    The name of the server playlist. It can be used only in the callback. To use outside, make a copy.
+ * @param[in] media_id    The ID of the media in playlist. It can be used only in the callback. To use outside, make a copy.
+ * @param[in] action    The received playback action
+ * @param[in] position    The received playback position (milliseconds)
+ * @param[in] user_data    The user data passed from the mc_server_set_playlist_command_received_cb() function
+ *
+ * @pre mc_server_set_playlist_command_received_cb()
+ *
+ * @see mc_server_set_playlist_command_received_cb()
+ */
+typedef void (*mc_server_playlist_command_received_cb)(const char* client_name, const char *playlist_name, const char *media_id, mc_playback_action_e action, unsigned long long position, void *user_data);
+
+/**
  * @brief Creates a media controller server.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
  *
@@ -624,6 +643,46 @@ int mc_server_unset_custom_command_received_cb(mc_server_h server);
 int mc_server_send_command_reply(mc_server_h server, const char *client_name, int result_code, bundle *data);
 
 /**
+ * @brief Sets the callback for receiving playlist command from client.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @param[in] server    The handle to media controller server
+ * @param[in] callback      The callback to be invoked when media controller server receives playlist command from client.
+ * @param[in] user_data   The user data to be passed to the callback function
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_CONTROLLER_ERROR_NONE Successful
+ * @retval #MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller server handle by calling mc_server_create().
+ * @see mc_server_create()
+ * @see mc_server_destroy()
+ */
+int mc_server_set_playlist_command_received_cb(mc_server_h server, mc_server_playlist_command_received_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the callback for receiving playlist command from client.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @param[in] server    The handle to media controller server
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #MEDIA_CONTROLLER_ERROR_NONE Successful
+ * @retval #MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller server handle by calling mc_server_create().
+ * @see mc_server_create()
+ * @see mc_server_destroy()
+ */
+int mc_server_unset_playlist_command_received_cb(mc_server_h server);
+
+/**
  * @brief Destroys media controller server.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
  * @param[in] server The handle to media controller server
index a7517ad..1044234 100755 (executable)
@@ -1074,8 +1074,8 @@ int mc_client_send_playback_state_command(mc_client_h client, const char *server
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_server_table_exist [%d]", ret);
        mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
 
-       ret = mc_util_set_command_availabe(mc_client->client_name, MC_COMMAND_PLAYBACKSTATE, NULL);
-       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_availabe [%d]", ret);
+       ret = mc_util_set_command_available(mc_client->client_name, MC_COMMAND_PLAYBACKSTATE, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
 
        message = g_strdup_printf("%s%s%d", mc_client->client_name, MC_STRING_DELIMITER, state);
        mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail making message [%d]", ret);
@@ -1106,8 +1106,8 @@ int mc_client_send_playback_action(mc_client_h client, const char *server_name,
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_server_table_exist [%d]", ret);
        mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
 
-       ret = mc_util_set_command_availabe(mc_client->client_name, MC_COMMAND_PLAYBACKACTION, NULL);
-       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_availabe [%d]", ret);
+       ret = mc_util_set_command_available(mc_client->client_name, MC_COMMAND_PLAYBACKACTION, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
 
        message = g_strdup_printf("%s%s%d", mc_client->client_name, MC_STRING_DELIMITER, action);
        mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail making message [%d]", ret);
@@ -1137,8 +1137,8 @@ int mc_client_send_playback_position_command(mc_client_h client, const char *ser
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_server_table_exist [%d]", ret);
        mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
 
-       ret = mc_util_set_command_availabe(mc_client->client_name, MC_COMMAND_PLAYBACKPOSITION, NULL);
-       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_availabe [%d]", ret);
+       ret = mc_util_set_command_available(mc_client->client_name, MC_COMMAND_PLAYBACKPOSITION, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
 
        message = g_strdup_printf("%s%s%llu", mc_client->client_name, MC_STRING_DELIMITER, position);
        mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail making message [%d]", ret);
@@ -1169,8 +1169,8 @@ int mc_client_send_shuffle_mode_command(mc_client_h client, const char *server_n
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_server_table_exist [%d]", ret);
        mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
 
-       ret = mc_util_set_command_availabe(mc_client->client_name, MC_COMMAND_SHUFFLE, NULL);
-       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_availabe [%d]", ret);
+       ret = mc_util_set_command_available(mc_client->client_name, MC_COMMAND_SHUFFLE, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
 
        message = g_strdup_printf("%s%s%d", mc_client->client_name, MC_STRING_DELIMITER, shuffle_mode);
        mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail making message [%d]", ret);
@@ -1201,8 +1201,8 @@ int mc_client_send_repeat_mode_command(mc_client_h client, const char *server_na
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_server_table_exist [%d]", ret);
        mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
 
-       ret = mc_util_set_command_availabe(mc_client->client_name, MC_COMMAND_REPEAT, NULL);
-       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_availabe [%d]", ret);
+       ret = mc_util_set_command_available(mc_client->client_name, MC_COMMAND_REPEAT, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
 
        message = g_strdup_printf("%s%s%d", mc_client->client_name, MC_STRING_DELIMITER, repeat_mode);
        mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail making message [%d]", ret);
@@ -1234,8 +1234,8 @@ int mc_client_send_custom_command(mc_client_h client, const char *server_name, c
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_server_table_exist [%d]", ret);
        mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
 
-       ret = mc_util_set_command_availabe(mc_client->client_name, MC_COMMAND_CUSTOM, command);
-       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_availabe [%d]", ret);
+       ret = mc_util_set_command_available(mc_client->client_name, MC_COMMAND_CUSTOM, command);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
 
        if (callback) {
                char *interface_name_for_reply = mc_util_get_interface_name(MC_CLIENT, mc_client->client_name);
@@ -1270,6 +1270,40 @@ int mc_client_send_custom_command(mc_client_h client, const char *server_name, c
        return ret;
 }
 
+int mc_client_send_playlist_command(mc_client_h client, const char *server_name, const char *playlist_name, const char *media_id, mc_playback_action_e action, unsigned long long position)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       char *message = NULL;
+       media_controller_client_s *mc_client = (media_controller_client_s *)client;
+       bool exist_server = FALSE;
+
+       mc_retvm_if(mc_client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       mc_retvm_if(!MC_STRING_VALID(server_name), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid server_name");
+       mc_retvm_if(!MC_STRING_VALID(playlist_name), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid playlist_name");
+       mc_retvm_if(!MC_STRING_VALID(media_id), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid media_id");
+       mc_retvm_if(((action < MC_PLAYBACK_ACTION_PLAY) || (action > MC_PLAYBACK_ACTION_TOGGLE_PLAY_PAUSE)), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid action");
+
+       ret = mc_db_check_server_table_exist(mc_client->db_handle, server_name, &exist_server);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_server_table_exist [%d]", ret);
+       mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
+
+       ret = mc_util_set_command_available(mc_client->client_name, MC_COMMAND_PLAY_PLAYLIST, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
+
+       message = g_strdup_printf("%s%s%s%s%s%s%d%s%llu", mc_client->client_name, MC_STRING_DELIMITER, playlist_name, MC_STRING_DELIMITER, media_id, MC_STRING_DELIMITER, action, MC_STRING_DELIMITER, position);
+       mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail making message [%d]", ret);
+
+       char *interface_name = mc_util_get_interface_name(MC_SERVER, server_name);
+       ret = mc_ipc_send_message(mc_client->dconn, NULL, interface_name, MC_DBUS_SIGNAL_NAME_PLAYBACK_PLAYLIST, message, 0);
+       if (ret != MEDIA_CONTROLLER_ERROR_NONE)
+               mc_error("Error mc_ipc_send_message [%d]", ret);
+
+       MC_SAFE_G_FREE(message);
+       MC_SAFE_G_FREE(interface_name);
+
+       return ret;
+}
+
 int mc_client_destroy(mc_client_h client)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
index f5abcc1..f27f325 100755 (executable)
@@ -106,6 +106,8 @@ static void __server_playback_state_command_cb(const char *interface_name, const
 {
        gchar **params = NULL;
        media_controller_receiver_s *receiver = (media_controller_receiver_s *)user_data;
+       int value = 0;
+
        mc_retm_if(receiver == NULL, "reciever is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
@@ -117,13 +119,12 @@ static void __server_playback_state_command_cb(const char *interface_name, const
        params = g_strsplit(message, MC_STRING_DELIMITER, 0);
        mc_retm_if(params == NULL, "invalid playback state command");
 
-       if (mc_util_get_command_availabe(params[0], MC_COMMAND_PLAYBACKSTATE, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
+       if (mc_util_get_command_available(params[0], MC_COMMAND_PLAYBACKSTATE, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error permission denied");
                g_strfreev(params);
                return;
        }
 
-       int value = 0;
        if (mc_safe_strtoi(params[1], &value) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error get recieved value");
                g_strfreev(params);
@@ -139,6 +140,8 @@ static void __server_playback_action_cb(const char *interface_name, const char *
 {
        gchar **params = NULL;
        media_controller_receiver_s *receiver = (media_controller_receiver_s *)user_data;
+       int value = 0;
+
        mc_retm_if(receiver == NULL, "reciever is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
@@ -150,13 +153,12 @@ static void __server_playback_action_cb(const char *interface_name, const char *
        params = g_strsplit(message, MC_STRING_DELIMITER, 0);
        mc_retm_if(params == NULL, "invalid playback_action command");
 
-       if (mc_util_get_command_availabe(params[0], MC_COMMAND_PLAYBACKACTION, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
+       if (mc_util_get_command_available(params[0], MC_COMMAND_PLAYBACKACTION, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error permission denied");
                g_strfreev(params);
                return;
        }
 
-       int value = 0;
        if (mc_safe_strtoi(params[1], &value) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error get recieved value");
                g_strfreev(params);
@@ -172,6 +174,8 @@ static void __server_playback_position_command_cb(const char *interface_name, co
 {
        gchar **params = NULL;
        media_controller_receiver_s *receiver = (media_controller_receiver_s *)user_data;
+       unsigned long long value = 0;
+
        mc_retm_if(receiver == NULL, "reciever is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
@@ -183,13 +187,12 @@ static void __server_playback_position_command_cb(const char *interface_name, co
        params = g_strsplit(message, MC_STRING_DELIMITER, 0);
        mc_retm_if(params == NULL, "invalid playback_position command");
 
-       if (mc_util_get_command_availabe(params[0], MC_COMMAND_PLAYBACKPOSITION, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
+       if (mc_util_get_command_available(params[0], MC_COMMAND_PLAYBACKPOSITION, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error permission denied");
                g_strfreev(params);
                return;
        }
 
-       unsigned long long value = 0;
        if (mc_safe_strtoull(params[1], &value) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error get recieved value");
                g_strfreev(params);
@@ -205,6 +208,8 @@ static void __server_shuffle_mode_command_cb(const char *interface_name, const c
 {
        gchar **params = NULL;
        media_controller_receiver_s *receiver = (media_controller_receiver_s *)user_data;
+       int value = 0;
+
        mc_retm_if(receiver == NULL, "reciever is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
@@ -216,13 +221,12 @@ static void __server_shuffle_mode_command_cb(const char *interface_name, const c
        params = g_strsplit(message, MC_STRING_DELIMITER, 0);
        mc_retm_if(params == NULL, "invalid shuffle_mode command");
 
-       if (mc_util_get_command_availabe(params[0], MC_COMMAND_SHUFFLE, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
+       if (mc_util_get_command_available(params[0], MC_COMMAND_SHUFFLE, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error permission denied");
                g_strfreev(params);
                return;
        }
 
-       int value = 0;
        if (mc_safe_strtoi(params[1], &value) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error get recieved value");
                g_strfreev(params);
@@ -238,6 +242,8 @@ static void __server_repeat_mode_command_cb(const char *interface_name, const ch
 {
        gchar **params = NULL;
        media_controller_receiver_s *receiver = (media_controller_receiver_s *)user_data;
+       int value = 0;
+
        mc_retm_if(receiver == NULL, "reciever is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
@@ -249,13 +255,12 @@ static void __server_repeat_mode_command_cb(const char *interface_name, const ch
        params = g_strsplit(message, MC_STRING_DELIMITER, 0);
        mc_retm_if(params == NULL, "invalid repeat_mode command");
 
-       if (mc_util_get_command_availabe(params[0], MC_COMMAND_REPEAT, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
+       if (mc_util_get_command_available(params[0], MC_COMMAND_REPEAT, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error permission denied");
                g_strfreev(params);
                return;
        }
 
-       int value = 0;
        if (mc_safe_strtoi(params[1], &value) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error get recieved value");
                g_strfreev(params);
@@ -289,7 +294,7 @@ static void __server_custom_command_cb(const char *interface_name, const char *s
        if (params[0])
                sender = strdup(params[0]);
 
-       if (mc_util_get_command_availabe(sender, MC_COMMAND_CUSTOM, params[1]) != MEDIA_CONTROLLER_ERROR_NONE) {
+       if (mc_util_get_command_available(sender, MC_COMMAND_CUSTOM, params[1]) != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error permission denied");
                MC_SAFE_FREE(sender);
                g_strfreev(params);
@@ -309,6 +314,47 @@ static void __server_custom_command_cb(const char *interface_name, const char *s
        g_strfreev(params);
 }
 
+static void __server_play_playlist_command_cb(const char *interface_name, const char *signal_name, const char *message, int size, void *user_data)
+{
+       gchar **params = NULL;
+       media_controller_receiver_s *receiver = (media_controller_receiver_s *)user_data;
+       int action = 0;
+       unsigned long long position = 0;
+
+       mc_retm_if(receiver == NULL, "reciever is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
+
+       mc_server_playlist_command_received_cb callback = receiver->callback;
+       mc_retm_if(receiver->callback == NULL, "mc_server_playlist_command_received_cb is NULL");
+
+       mc_debug("__server_play_playlist_command_cb(%s, %s, %s, %d, %p)", interface_name, signal_name, message, size, user_data);
+
+       params = g_strsplit(message, MC_STRING_DELIMITER, 0);
+       mc_retm_if(params == NULL, "invalid play_playlist command");
+
+       if (mc_util_get_command_available(params[0], MC_COMMAND_PLAY_PLAYLIST, NULL) != MEDIA_CONTROLLER_ERROR_NONE) {
+               mc_error("Error permission denied");
+               g_strfreev(params);
+               return;
+       }
+
+       if (mc_safe_strtoi(params[3], &action) != MEDIA_CONTROLLER_ERROR_NONE) {
+               mc_error("Error get recieved action value");
+               g_strfreev(params);
+               return;
+       }
+
+       if (mc_safe_strtoull(params[4], &position) != MEDIA_CONTROLLER_ERROR_NONE) {
+               mc_error("Error get recieved position value");
+               g_strfreev(params);
+               return;
+       }
+
+       callback(params[0], params[1], params[2], (mc_playback_action_e)action, position, receiver->user_data);
+
+       g_strfreev(params);
+}
+
 static int __mc_server_current_is_latest(media_controller_server_s *mc_server, bool *is_latest)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -851,6 +897,43 @@ int mc_server_send_command_reply(mc_server_h server, const char *client_name, in
        return ret;
 }
 
+int mc_server_set_playlist_command_received_cb(mc_server_h server, mc_server_playlist_command_received_cb callback, void *user_data)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_server_s *mc_server = (media_controller_server_s *)server;
+
+       mc_retvm_if(mc_server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       mc_retvm_if(callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "callback is NULL");
+
+       mc_server->play_playlist_reciever.callback = callback;
+       mc_server->play_playlist_reciever.user_data = user_data;
+
+       char *interface_name = mc_util_get_interface_name(MC_SERVER, mc_server->server_name);
+       ret = mc_ipc_register_listener(&mc_server->listeners, mc_server->dconn, interface_name, MC_DBUS_SIGNAL_NAME_PLAYBACK_PLAYLIST, __server_play_playlist_command_cb, (void *)&(mc_server->play_playlist_reciever));
+
+       MC_SAFE_FREE(interface_name);
+
+       return ret;
+}
+
+int mc_server_unset_playlist_command_received_cb(mc_server_h server)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_server_s *mc_server = (media_controller_server_s *)server;
+
+       mc_retvm_if(mc_server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       char *interface_name = mc_util_get_interface_name(MC_SERVER, mc_server->server_name);
+       ret = mc_ipc_unregister_listener(&mc_server->listeners, mc_server->dconn, interface_name, MC_DBUS_SIGNAL_NAME_PLAYBACK_PLAYLIST);
+
+       mc_server->play_playlist_reciever.callback = NULL;
+       mc_server->play_playlist_reciever.user_data = NULL;
+
+       MC_SAFE_FREE(interface_name);
+
+       return ret;
+}
+
 int mc_server_create(mc_server_h *server)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
index aa6fbd5..42964c8 100755 (executable)
@@ -130,7 +130,7 @@ int mc_util_make_filter_interface_name(const char *prefix, const char *filter, c
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
-int mc_util_set_command_availabe(const char *name, const char *command_type, const char *command)
+int mc_util_set_command_available(const char *name, const char *command_type, const char *command)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        char *message = NULL;
@@ -152,7 +152,7 @@ int mc_util_set_command_availabe(const char *name, const char *command_type, con
        return ret;
 }
 
-int mc_util_get_command_availabe(const char *name, const char *command_type, const char *command)
+int mc_util_get_command_available(const char *name, const char *command_type, const char *command)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        char *message = NULL;
index 61b9fb7..c6d1de4 100755 (executable)
@@ -39,6 +39,7 @@
 
 static mc_client_h g_mc_client;
 static char *g_server_name;
+static char *g_playlist_name;
 
 static mc_playback_states_e g_playback_state;
 static unsigned long long g_playback_position;
@@ -274,7 +275,6 @@ static gboolean _get_info(int type)
        mc_shuffle_mode_e shuffle_mode;
        mc_repeat_mode_e repeate_mode;
        bundle *playlist = NULL;
-       char *playlist_name = NULL;
        int bundle_cnt = 0;
 
        mc_debug_fenter();
@@ -334,13 +334,13 @@ static gboolean _get_info(int type)
                g_print("repeate mode: %d", repeate_mode);
                break;
        case 6:
-               ret = mc_client_get_server_playlist(g_mc_client, g_server_name, &playlist_name, &playlist);
+               ret = mc_client_get_server_playlist(g_mc_client, g_server_name, &g_playlist_name, &playlist);
                mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_playlist [%d]", ret);
 
                if (playlist != NULL) {
                        bundle_cnt = bundle_get_count(playlist);
 
-                       g_print("playlist_name [%s] bundle_cnt [%d] \n", playlist_name, bundle_cnt);
+                       g_print("playlist_name [%s] bundle_cnt [%d] \n", g_playlist_name, bundle_cnt);
 
                        bundle_foreach(playlist, __playlist_get_info_cb, NULL);
 
@@ -349,8 +349,6 @@ static gboolean _get_info(int type)
                        g_print("There is no playlist \n");
                }
 
-               MC_SAFE_FREE(playlist_name);
-
                break;
        default:
                g_print("== unknown type!\n");
@@ -374,20 +372,20 @@ static gboolean _send()
                g_playback_state = MC_PLAYBACK_STATE_PLAYING;
        ret = mc_client_send_playback_state_command(g_mc_client, g_server_name, g_playback_state);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to send playback state command %d", ret);
+               g_print("Fail to send playback state command [%d]", ret);
                return FALSE;
        }
 
        ret = mc_client_send_playback_action(g_mc_client, g_server_name, action);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to send playback action command %d", ret);
+               g_print("Fail to send playback action command [%d]", ret);
                return FALSE;
        }
 
        g_playback_position += 1000;
        ret = mc_client_send_playback_position_command(g_mc_client, g_server_name, g_playback_position);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to send playback position command %d", ret);
+               g_print("Fail to send playback position command [%d]", ret);
                return FALSE;
        }
 
@@ -397,7 +395,7 @@ static gboolean _send()
                g_shuffle_mode = MC_SHUFFLE_MODE_OFF;
        ret = mc_client_send_shuffle_mode_command(g_mc_client, g_server_name, g_shuffle_mode);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to send shuffle mode command %d", ret);
+               g_print("Fail to send shuffle mode command [%d]", ret);
                return FALSE;
        }
 
@@ -407,7 +405,13 @@ static gboolean _send()
                g_repeat_mode = MC_REPEAT_MODE_OFF;
        ret = mc_client_send_repeat_mode_command(g_mc_client, g_server_name, g_repeat_mode);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to send shuffle mode command %d", ret);
+               g_print("Fail to send shuffle mode command [%d]", ret);
+               return FALSE;
+       }
+
+       ret = mc_client_send_playlist_command(g_mc_client, g_server_name, g_playlist_name, "1", MC_PLAYBACK_ACTION_PLAY, 300);
+       if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+               g_print("Fail to send play playlist item [%d]", ret);
                return FALSE;
        }
 
@@ -449,6 +453,9 @@ static gboolean _destroy()
 
        g_mc_client = NULL;
 
+       MC_SAFE_FREE(g_server_name);
+       MC_SAFE_FREE(g_playlist_name);
+
        mc_debug_fleave();
 
        return TRUE;
index d6843f2..0c76628 100755 (executable)
@@ -99,6 +99,11 @@ void __repeat_mode_command_received_cb(const char *client_name, mc_repeat_mode_e
        mc_debug("[%s] recieved repeat mode:[%d] from [%s]", client_name, repeat_mode, client_name);
 }
 
+void __playlist_play_received_cb(const char* client_name, const char *playlist_name, const char *media_id, mc_playback_action_e action, unsigned long long position, void *user_data)
+{
+       mc_debug("recieved playlist play : playlist_name[%s] media_id[%s] action[%d] position[%llu] from [%s]", playlist_name, media_id, action, position, client_name);
+}
+
 void __custom_command_received_cb(const char *client_name, const char *command, bundle *data, void *user_data)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -238,25 +243,31 @@ static gboolean _set_cb()
 
        ret = mc_server_set_playback_position_command_received_cb(g_mc_server, __playback_position_command_received_cb, NULL);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to set playback_position_command_reciveed_cb");
+               g_print("Fail to set mc_server_set_playback_position_command_received_cb");
                return FALSE;
        }
 
        ret = mc_server_set_shuffle_mode_command_received_cb(g_mc_server, __shuffle_mode_command_received_cb, NULL);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to set shuffle_mode_command_reciveed_cb");
+               g_print("Fail to set mc_server_set_shuffle_mode_command_received_cb");
                return FALSE;
        }
 
        ret = mc_server_set_repeat_mode_command_received_cb(g_mc_server, __repeat_mode_command_received_cb, NULL);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to set repeat_mode_command_reciveed_cb");
+               g_print("Fail to set mc_server_set_repeat_mode_command_received_cb");
                return FALSE;
        }
 
        ret = mc_server_set_custom_command_received_cb(g_mc_server, __custom_command_received_cb, NULL);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
-               g_print("Fail to set custom_command_reciveed_cb");
+               g_print("Fail to set mc_server_set_custom_command_received_cb");
+               return FALSE;
+       }
+
+       ret = mc_server_set_playlist_command_received_cb(g_mc_server, __playlist_play_received_cb, NULL);
+       if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+               g_print("Fail to set mc_server_set_playlist_command_received_cb");
                return FALSE;
        }