*
* @remarks The callback is called in the dbus event loop.
*
- * @param[in] server_name The app_id of the updated media controller server, it can be used only in the callback. To use outside, make a copy.
+ * @param[in] server_name The app_id of the media controller server which sent the notification. It can be used only in the callback. To use outside, make a copy.
* @param[in] state The state of the updated media controller server
* @param[in] user_data The user data passed from the mc_client_set_server_update_cb() function
*
*
* @remarks The callback is called in the dbus event loop.
*
- * @param[in] server_name The app_id of the updated media controller server. it can be used only in the callback. To use outside, make a copy.
- * @param[in] playback The playback information of the updated media controller server. it can be used only in the callback.
+ * @param[in] server_name The app_id of the media controller server which sent the notification. It can be used only in the callback. To use outside, make a copy.
+ * @param[in] playback The playback information of the updated media controller server. It can be used only in the callback.
* @param[in] user_data The user data passed from the mc_client_set_playback_update_cb() function
*
* @pre mc_client_set_playback_update_cb()
*
* @remarks The callback is called in the dbus event loop.
*
- * @param[in] server_name The app_id of the updated media controller server. it can be used only in the callback. To use outside, make a copy.
- * @param[in] metadata the metadata of the updated media controller server. it can be used only in the callback.
+ * @param[in] server_name The app_id of the media controller server which sent the notification. It can be used only in the callback. To use outside, make a copy.
+ * @param[in] metadata the metadata of the updated media controller server. It can be used only in the callback.
* @param[in] user_data The user data passed from the mc_client_set_metadata_update_cb() function
*
* @pre mc_client_set_metadata_update_cb()
*
* @remarks The callback is called in the dbus event loop.
*
- * @param[in] server_name The app_id of the updated media controller server, it can be used only in the callback. To use outside, make a copy.
+ * @param[in] server_name The app_id of the media controller server which sent the notification. It can be used only in the callback. To use outside, make a copy.
* @param[in] mode The shuffle mode of the updated media controller server
* @param[in] user_data The user data passed from the mc_client_set_shuffle_mode_update_cb() function
*
*
* @remarks The callback is called in the dbus event loop.
*
- * @param[in] server_name The app_id of the updated media controller server, it can be used only in the callback. To use outside, make a copy.
+ * @param[in] server_name The app_id of the media controller server which sent the notification. It can be used only in the callback. To use outside, make a copy.
* @param[in] mode The repeat mode of the updated media controller server
* @param[in] user_data The user data passed from the mc_client_set_repeat_mode_update_cb() function
*
*
* @remarks The callback is called in the dbus event loop.
*
- * @param[in] server_name The app_id of the activated media controller server, it can be used only in the callback. To use outside, make a copy.
+ * @param[in] server_name The app_id of the activated media controller server. It can be used only in the callback. To use outside, make a copy.
* @param[in] user_data The user data passed from the mc_client_foreach_server() function
*
* @return @c true to continue with the next iteration of the loop,
* @brief Called when receiving the command processing result from the server.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
- * @remarks The callback is called in the dbus event loop. @a data should be released using bundle_free().
+ * @remarks The callback is called in the dbus event loop. @a data should be released using @c bundle_free().
*
- * @param[in] server_name The app_id of the updated media controller server, it can be used only in the callback. To use outside, make a copy.
+ * @param[in] server_name The app_id of the media controller server which sent the reply, It can be used only in the callback. To use outside, make a copy.
* @param[in] result_code The result code of custom command
* @param[in] data The extra data
* @param[in] user_data The user data passed from the mc_client_send_custom_command() function
*
* @remarks The callback is called in the dbus event loop.
*
- * @param[in] server_name The app_id of the subscribed media controller server, it can be used only in the callback. To use outside, make a copy.
+ * @param[in] server_name The app_id of the subscribed media controller server. It can be used only in the callback. To use outside, make a copy.
* @param[in] user_data The user data passed from the mc_client_foreach_server_subscribed() function
*
* @return @c true to continue with the next iteration of the loop,
*/
typedef bool (*mc_subscribed_server_cb)(const char *server_name, void *user_data);
+/**
+ * @brief Called when updating the playlist of the media controller server.
+ * @since_tizen 5.0
+ *
+ * @remarks The callback is called in the dbus event loop. @a data is a bundle. A bundle is a set of key-value pairs. "item id" is the key and "item metadata" is the value.
+ *
+ * @param[in] server_name The app_id of the media controller server which sent the notification. It can be used only in the callback. To use outside, make a copy.
+ * @param[in] mode The playlist update mode of the updated media controller server
+ * @param[in] playlist_name Updated playlist name. It can be used only in the callback. To use outside, make a copy.
+ * @param[in] data The playlist of the media controller server. When the playlist has been removed or it has no items after the change, @a data is NULL. It can be used only in the callback. To use outside, make a copy using @c bundle_dup().
+ * @param[in] user_data The user data passed from the mc_client_set_playlist_update_cb() function
+ *
+ * @pre mc_client_set_playlist_update_cb()
+ *
+ * @see mc_client_set_playlist_update_cb()
+ * @see mc_server_update_playlist()
+ */
+typedef void (*mc_playlist_updated_cb)(const char *server_name, mc_playlist_update_mode_e mode, const char *playlist_name, bundle *data, void *user_data);
+
/**
* @brief Creates a media controller client.
* @details The media controller client binds the latest media controller server when handlers are created.
* @privlevel public
* @privilege %http://tizen.org/privilege/mediacontroller.client
*
- * @remarks The @a client should be released using mc_client_destroy().
+ * @remarks The @a client should be released using @c mc_client_destroy().
*
* @param[out] client The handle to the media controller client
* @return @c 0 on success,
/**
* @brief Sets the callback for monitoring status of the media controller server.
- * @details If media controller client call this function, basically the media controller client receive the callback from all media controller servers.
+ * @details The media controller client which calls this function will receive notifications from all media controller servers.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
/**
* @brief Sets the callback for monitoring playback status of the media controller server.
- * @details If media controller client call this function, basically the media controller client receive the callback from all media controller servers. \n
+ * @details The media controller client which calls this function will receive notifications from all media controller servers. \n
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
/**
* @brief Sets the callback for monitoring metadata status of the media controller server.
- * @details If media controller client call this function, basically the media controller client receive the callback from all media controller servers.
+ * @details The media controller client which calls this function will receive notifications from all media controller servers.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
/**
* @brief Sets the callback for monitoring shuffle mode of the media controller server.
- * @details If media controller client call this function, basically the media controller client receive the callback from all media controller servers.
+ * @details The media controller client which calls this function will receive notifications from all media controller servers.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
/**
* @brief Sets the callback for monitoring repeat mode of the media controller server.
- * @details If media controller client call this function, basically the media controller client receive the callback from all media controller servers.
+ * @details The media controller client which calls this function will receive notifications from all media controller servers.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
*/
int mc_client_unset_repeat_mode_update_cb(mc_client_h client);
+/**
+ * @brief Sets the callback for monitoring playlist status of the media controller server.
+ * @details The media controller client which calls this function will receive notifications from all media controller servers.
+ * @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] callback The callback to be invoked when the playlist status is changed
+ * @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 client handle by calling mc_client_create().
+ * @see mc_client_create()
+ * @see mc_client_destroy()
+ */
+int mc_client_set_playlist_update_cb(mc_client_h client, mc_playlist_updated_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the callback for monitoring playlist status of the media controller server.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @param[in] client The handle to the media controller client
+ * @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()
+ * @see mc_client_destroy()
+ */
+int mc_client_unset_playlist_update_cb(mc_client_h client);
+
/**
* @brief Subscribes media controller server for monitoring status.
* @details If media controller client subscribe media controller server, \n
* If there is no playback info, return value of the playback is NULL.
*
* @param[in] client The handle to the media controller client
- * @param[in] server_name The app_id of the server to requesting
+ * @param[in] server_name The app_id of the media controller server
* @param[out] playback The handle to playback
* @return @c 0 on success,
* otherwise a negative error value
* If there is no metadata, return value of the metadata is NULL.
*
* @param[in] client The handle to the media controller client
- * @param[in] server_name The app_id of the server to requesting
+ * @param[in] server_name The app_id of the media controller server
* @param[out] metadata The handle to metadata
* @return @c 0 on success,
* otherwise a negative error value
* @remarks If there is no shuffle mode info, return value is #MC_SHUFFLE_MODE_OFF.
*
* @param[in] client The handle to the media controller client
- * @param[in] server_name The app_id of the server to requesting
+ * @param[in] server_name The app_id of the media controller server
* @param[out] mode The info of the latest shuffle mode
* @return @c 0 on success,
* otherwise a negative error value
* @remarks If there is no repeat mode info, return value is #MC_REPEAT_MODE_OFF.
*
* @param[in] client The handle to the media controller client
- * @param[in] server_name The app_id of the server to requesting
+ * @param[in] server_name The app_id of the media controller server
* @param[out] mode The info of the latest shuffle mode
* @return @c 0 on success,
* otherwise a negative error value
*/
int mc_client_get_server_repeat_mode(mc_client_h client, const char *server_name, mc_repeat_mode_e *mode);
+ /**
+ * @brief Gets the playlist.
+ * @details The media controller client will get the playlist information from @a server_name.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @remarks The @a playlist_name should be released using free(). \n
+ * @a playlist is a bundle. A bundle is a set of key-value pairs. "item id" is the key and "item metadata" is the value. \n
+ * And also the @a playlist should be released using @c bundle_free(). \n
+ * If there is no playlist, return value of @a playlist_name and @a playlist is NULL.
+ *
+ * @param[in] client The handle to the media controller client
+ * @param[in] server_name The app_id of the media controller server
+ * @param[out] playlist_name The playlist name of the server
+ * @param[out] playlist The item list of the playlist
+ * @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
+ * @see mc_client_create()
+ * @see mc_client_destroy()
+ * @see mc_server_update_playlist()
+ */
+int mc_client_get_server_playlist(mc_client_h client, const char *server_name, char **playlist_name, bundle **playlist);
+
/**
* @brief Retrieves all activated Server.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
#include <db-util.h>
#include <sqlite3.h>
#include <tzplatform_config.h>
+#include <bundle.h>
#define FAT_FILEPATH_LEN_MAX 4096 /* inc null */
#define MC_FILE_PATH_LEN_MAX FAT_FILEPATH_LEN_MAX /**< File path max length (include file name) on file system */
int mc_db_get_metadata_info(void *handle, const char *server_name, mc_metadata_h *metadata);
int mc_db_get_shuffle_mode(void *handle, const char *server_name, mc_shuffle_mode_e *mode);
int mc_db_get_repeat_mode(void *handle, const char *server_name, mc_repeat_mode_e *mode);
+int mc_db_get_playlist(void *handle, const char *server_name, char **playlist_name, bundle **playlist);
int mc_db_insert_server_address_into_table(void *db_handle, const char *table_name, char *address);
int mc_db_delete_server_address_from_table(void *db_handle, const char *table_name, char *address);
int mc_db_update_server_state(void *handle, const char *server_name, mc_server_state_e server_state);
int mc_db_update_server_and_playback_state(void *handle, const char *server_name, mc_server_state_e server_state, mc_playback_states_e playback_state);
int mc_db_update_latest_server_table(void *handle, const char *server_name);
+int mc_db_remove_playlist(void *handle, const char *server_name);
+int mc_db_update_playlist(void *handle, const char *server_name, const char *playlist_name, bundle *data);
#endif /*__TIZEN_MULTIMEDIA_MEDIA_CONTROLLER_DB_H__*/
#define MC_DBUS_SIGNAL_NAME_REPEAT_CMD "repeat_cmd"
#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_COMMAND_PLAYBACKSTATE "_pb_state_cmd_"
#define MC_COMMAND_PLAYBACKACTION "_pb_action_cmd_"
media_controller_receiver_s shuffle_cb;
media_controller_receiver_s repeat_cb;
media_controller_receiver_s reply_cb;
+ media_controller_receiver_s playlist_cb;
} media_controller_client_s;
/* formal callback to receive signal */
*
* @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] 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] state The received playback state
* @param[in] user_data The user data passed from the mc_server_set_playback_state_command_received_cb() function
*
typedef void (*mc_server_playback_state_command_received_cb)(const char* client_name, mc_playback_states_e state, void *user_data);
/**
- * @brief Called when the server receives the playback action commandfrom the client.
+ * @brief Called when the server receives the playback action 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] 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] action The received playback action
* @param[in] user_data The user data passed from the mc_server_set_playback_action_received_cb() function
*
*
* @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] 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] user_data The user data passed from the mc_server_set_playback_position_command_received_cb() function
*
*
* @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] 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] shuffle_mode The received shuffle_mode
* @param[in] user_data The user data passed from the mc_server_set_shuffle_mode_command_received_cb() function
*
*
* @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] 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] repeat_mode The received repeat mode
* @param[in] user_data The user data passed from the mc_server_set_repeat_mode_command_received_cb() function
*
*
* @remarks The callback is called in the dbus event loop. @a data should be released using bundle_free().
*
- * @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] command The received command. it can be used only in the callback. To use outside, make a copy.
+ * @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] command The received command. It can be used only in the callback. To use outside, make a copy.
* @param[in] data The extra data
* @param[in] user_data The user data passed from the mc_server_set_custom_command_received_cb() function
*
/**
* @brief Updates the modified metadata info.
- * @details If this function is called, the updated metadata will be sent to all controllers.
+ * @details If this function is called, the updated metadata will be sent to all clients.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
/**
* @brief Updates the modified shuffle mode.
- * @details If this function is called, the updated mode information will be sent to all controllers.
+ * @details If this function is called, the updated mode information will be sent to all clients.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
/**
* @brief Updates the modified repeat mode.
- * @details If this function is called, the updated mode information will be sent to all controllers.
+ * @details If this function is called, the updated mode information will be sent to all clients.
* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
*
* @privlevel public
*/
int mc_server_update_repeat_mode(mc_server_h server, mc_repeat_mode_e mode);
+/**
+ * @brief Updates the modified playlist info.
+ * @details If this function is called, the updated playlist will be sent to all clients. \n
+ * The server can register only one playlist. If a new one is registered, the old one is removed. \n
+ * @a data is a bundle. A bundle is a set of key-value pairs. "item id" is the key and "item metadata" is the value. \n
+ * Therefore you should fill the metadata order using #mc_meta_e. \n
+ * If there are no playlist items or the server wants to remove the playlist, set @data to NULL.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @param[in] server The handle to media controller server
+ * @param[in] mode The playlist update status
+ * @param[in] playlist_name The name of the server playlist
+ * @param[in] data The item list of playlist.
+ *
+ * @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_OUT_OF_MEMORY File does not exist
+ * @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()
+ *
+ * @code
+ #include <media_controller_server.h>
+ #include <bundle.h>
+ const char *playlist_item[11];
+ bundle * b = NULL;
+
+ playlist_item[MC_META_MEDIA_TITLE] = "title";
+ playlist_item[MC_META_MEDIA_ARTIST] = "artist";
+ playlist_item[MC_META_MEDIA_ALBUM] = "album";
+ playlist_item[MC_META_MEDIA_AUTHOR] = "author";
+ playlist_item[MC_META_MEDIA_GENRE] = "Rock";
+ playlist_item[MC_META_MEDIA_DURATION] = "100";
+ playlist_item[MC_META_MEDIA_DATE] = "2018";
+ playlist_item[MC_META_MEDIA_COPYRIGHT] = "copyright";
+ playlist_item[MC_META_MEDIA_DESCRIPTION] = "description";
+ playlist_item[MC_META_MEDIA_TRACK_NUM] = "9";
+ playlist_item[MC_META_MEDIA_PICTURE] = "picture_path";
+
+ bundle_add_str_array(b, "1", playlist_item, 11);
+
+ mc_server_update_playlist(server, MC_PLAYLIST_UPDATED, "playlist_1", b); //create or update playlist
+ mc_server_update_playlist(server, MC_PLAYLIST_REMOVED, "playlist_1", NULL); //remove playlist
+
+ bundle_free(bundle_data);
+
+ * @endcode
+ */
+int mc_server_update_playlist(mc_server_h server, mc_playlist_update_mode_e mode, const char *playlist_name, bundle *data);
+
/**
* @deprecated Deprecated since 5.0. Use mc_server_set_playback_action_received_cb() instead.
* @brief Sets the callback for receiving playback state command from client.
MC_SUBSCRIPTION_TYPE_METADATA, /**< Metadata */
MC_SUBSCRIPTION_TYPE_SHUFFLE_MODE, /**< Shuffle mode */
MC_SUBSCRIPTION_TYPE_REPEAT_MODE, /**< Repeat mode */
+ MC_SUBSCRIPTION_TYPE_PLAYLIST, /**< Playlist (Since 5.0) */
} mc_subscription_type_e;
+/**
+ * @brief Enumeration for the playlist update mode.
+ * @since_tizen 5.0
+ */
+typedef enum {
+ MC_PLAYLIST_UPDATED, /**< Create or Update playlist */
+ MC_PLAYLIST_REMOVED, /**< Remove playlist */
+} mc_playlist_update_mode_e;
+
/**
* @}
*/
Name: capi-media-controller
Summary: A media controller library in Tizen Native API
-Version: 0.1.52
+Version: 0.1.53
Release: 1
Group: Multimedia/API
License: Apache-2.0
g_strfreev(params);
}
+static void __client_playlist_cb(const char *interface_name, const char *signal_name, const char *message, int size, void *user_data)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ gchar **params = NULL;
+ bundle *playlist = NULL;
+ char *playlist_name = NULL;
+ mc_playlist_update_mode_e mode = MC_PLAYLIST_UPDATED;
+ media_controller_client_s *mc_client = (media_controller_client_s *)user_data;
+ mc_retm_if(mc_client == NULL, "mc_client is NULL");
+ mc_playlist_updated_cb callback = (mc_playlist_updated_cb)mc_client->playlist_cb.callback;
+
+ mc_retm_if(mc_client->playlist_cb.callback == NULL, "playlist_cb is NULL");
+ mc_retm_if(message == NULL, "message is NULL");
+
+ mc_debug("__client_playlist_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 custom data");
+
+ mode = atoi(params[1]);
+
+ if (mode == MC_PLAYLIST_UPDATED) {
+ ret = mc_db_get_playlist(mc_client->db_handle, params[0], &playlist_name, &playlist);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE)
+ mc_error("Fail to mc_db_get_playlist");
+ }
+
+ callback(params[0], mode, params[2], playlist, mc_client->playlist_cb.user_data);
+
+ g_strfreev(params);
+ MC_SAFE_FREE(playlist_name);
+ if (playlist != NULL)
+ bundle_free(playlist);
+
+ return;
+}
+
static int __mc_client_create(media_controller_client_s **mc_client)
{
int ret = MEDIA_CONTROLLER_ERROR_NONE;
return ret;
}
+int mc_client_set_playlist_update_cb(mc_client_h client, mc_playlist_updated_cb callback, void *user_data)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ media_controller_client_s *mc_client = (media_controller_client_s *)client;
+
+ mc_retvm_if(mc_client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+ mc_retvm_if(callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "callback is NULL");
+ mc_retvm_if(mc_client->playlist_cb.callback != NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "callback is already set");
+
+ mc_client->playlist_cb.callback = callback;
+ mc_client->playlist_cb.user_data = user_data;
+
+ ret = mc_ipc_register_listener(&mc_client->listeners, mc_client->dconn, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST,
+ __client_playlist_cb, (void *)(mc_client));
+
+ return ret;
+}
+
+int mc_client_unset_playlist_update_cb(mc_client_h client)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ media_controller_client_s *mc_client = (media_controller_client_s *)client;
+
+ mc_retvm_if(mc_client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+ ret = mc_ipc_unregister_listener(&mc_client->listeners, mc_client->dconn, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST);
+
+ ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->playlist_cb.filter_list, NULL, MC_DBUS_SIGNAL_NAME_PLAYLIST);
+
+ mc_client->playlist_cb.callback = NULL;
+ mc_client->playlist_cb.user_data = NULL;
+ mc_client->playlist_cb.filter_list = NULL;
+
+ return ret;
+}
+
int mc_client_subscribe(mc_client_h client, const mc_subscription_type_e subscription_type, const char *server_name)
{
int ret = MEDIA_CONTROLLER_ERROR_NONE;
ret = __mc_client_register_filter_listener(mc_client, &mc_client->repeat_cb.filter_list, server_name, MC_DBUS_SIGNAL_NAME_PLAYBACK_REPEAT,
__client_repeat_cb, (void *)&(mc_client->repeat_cb));
break;
+ case MC_SUBSCRIPTION_TYPE_PLAYLIST:
+ mc_retvm_if(mc_client->playlist_cb.callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid callback");
+
+ ret = mc_ipc_unregister_listener(&mc_client->listeners, mc_client->dconn, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST);
+ ret = __mc_client_register_filter_listener(mc_client, &mc_client->playlist_cb.filter_list, server_name, MC_DBUS_SIGNAL_NAME_PLAYLIST,
+ __client_playlist_cb, (void *)&(mc_client));
+ break;
default:
mc_error("Invalid subscription_type [%d]", subscription_type);
return MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER;
ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->repeat_cb.filter_list, server_name, MC_DBUS_SIGNAL_NAME_PLAYBACK_REPEAT);
break;
+ case MC_SUBSCRIPTION_TYPE_PLAYLIST:
+ mc_retvm_if(mc_client->playlist_cb.callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid callback. No list to unsubscribe");
+ mc_retvm_if(mc_client->playlist_cb.filter_list == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid filter_list. No list to unsubscribe");
+
+ ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->playlist_cb.filter_list, server_name, MC_DBUS_SIGNAL_NAME_PLAYLIST);
+ break;
default:
mc_error("Invalid subscription_type [%d]", subscription_type);
return MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER;
case MC_SUBSCRIPTION_TYPE_REPEAT_MODE:
filter_list = mc_client->repeat_cb.filter_list;
break;
+ case MC_SUBSCRIPTION_TYPE_PLAYLIST:
+ filter_list = mc_client->playlist_cb.filter_list;
+ break;
default:
mc_error("Invalid subscription_type [%d]", subscription_type);
return MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER;
return ret;
}
+int mc_client_get_server_playlist(mc_client_h client, const char *server_name, char **playlist_name, bundle **playlist)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ 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(playlist == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "playlist is NULL");
+
+ 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_db_get_playlist(mc_client->db_handle, server_name, playlist_name, playlist);
+
+ return ret;
+}
+
int mc_client_foreach_server(mc_client_h client, mc_activated_server_cb callback, void *user_data)
{
int ret = MEDIA_CONTROLLER_ERROR_NONE;
ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->metadata_cb.filter_list, NULL, MC_DBUS_SIGNAL_NAME_METADATA);
ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->shuffle_cb.filter_list, NULL, MC_DBUS_SIGNAL_NAME_PLAYBACK_SHUFFLE);
ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->repeat_cb.filter_list, NULL, MC_DBUS_SIGNAL_NAME_PLAYBACK_REPEAT);
+ ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->playlist_cb.filter_list, NULL, MC_DBUS_SIGNAL_NAME_PLAYLIST);
/*Unregister all listener*/
ret = mc_ipc_unregister_all_listener(&mc_client->listeners, mc_client->dconn);
MC_SERVER_FIELD_REPEAT_MODE,
} server_table_field_e;
+#define MC_DB_TABLE_PLAYLIST "server_playlist"
+
static int __mc_db_busy_handler(void *pData, int count)
{
MC_MILLISEC_SLEEP(50);
return MEDIA_CONTROLLER_ERROR_NONE;
}
+static int __db_get_playlist(void *handle, const char *server_name, char **playlist_name, bundle **playlist)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ char *sql_str = NULL;
+ sqlite3_stmt *stmt = NULL;
+ sqlite3 *db_handle = (sqlite3 *)handle;
+ char * _name = NULL;
+ bundle * _bundle_data = NULL;
+ bundle_raw *_raw_data = NULL;
+ int _raw_size = 0;
+
+ mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+ mc_retvm_if(server_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "server_name is NULL");
+
+ sql_str = sqlite3_mprintf("SELECT * from %s WHERE server_name = %Q", MC_DB_TABLE_PLAYLIST, server_name);
+ mc_retvm_if(!MC_STRING_VALID(sql_str), MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "SQL string is null");
+
+ mc_secure_debug("sql_str [%s]", sql_str);
+
+ ret = sqlite3_prepare_v2(db_handle, sql_str, strlen(sql_str), &stmt, NULL);
+ if (SQLITE_OK != ret) {
+ mc_error("prepare error [%s]", sqlite3_errmsg(db_handle));
+ SQLITE3_SAFE_FREE(sql_str);
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (SQLITE_ROW != ret) {
+ mc_debug("playlist is not exist [%s]", sqlite3_errmsg(db_handle));
+ SQLITE3_FINALIZE(stmt);
+ SQLITE3_SAFE_FREE(sql_str);
+ return MEDIA_CONTROLLER_ERROR_NONE;
+ }
+
+ while (SQLITE_ROW == ret) {
+ _name = g_strdup((const char *)sqlite3_column_text(stmt, 1));
+ _raw_data = (bundle_raw *)g_strdup((const char *)sqlite3_column_text(stmt, 2));
+ _raw_size = (int)sqlite3_column_int(stmt, 3);
+ ret = sqlite3_step(stmt);
+ }
+
+ SQLITE3_FINALIZE(stmt);
+ SQLITE3_SAFE_FREE(sql_str);
+
+ if ((_raw_data != NULL) && (_raw_size > 0)) {
+ _bundle_data = bundle_decode(_raw_data, _raw_size);
+
+ if (_bundle_data == NULL) {
+ mc_error("fail while decoding bundle");
+ MC_SAFE_FREE(_name);
+ MC_SAFE_FREE(_raw_data);
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
+ }
+ }
+
+ MC_SAFE_FREE(_raw_data);
+
+ *playlist_name = _name;
+ *playlist = _bundle_data;
+
+ return MEDIA_CONTROLLER_ERROR_NONE;
+}
+
static char* __mc_get_db_name(uid_t uid)
{
char result_psswd[MC_FILE_PATH_LEN_MAX] = {0, };
mc_error("end of row [%s]", sqlite3_errmsg(db_handle));
SQLITE3_FINALIZE(stmt);
SQLITE3_SAFE_FREE(sql_str);
- return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
+ return MEDIA_CONTROLLER_ERROR_NONE;
} else {
_metadata = (media_controller_metadata_s *)calloc(1, sizeof(media_controller_metadata_s));
if (_metadata == NULL) {
return ret;
}
+int mc_db_get_playlist(void *handle, const char *server_name, char **playlist_name, bundle **playlist)
+{
+ mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+ mc_retvm_if(server_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "server_name is NULL");
+
+ return __db_get_playlist(handle, server_name, playlist_name, playlist);
+}
+
int mc_db_insert_server_address_into_table(void *handle, const char *table_name, char *address)
{
int ret = MEDIA_CONTROLLER_ERROR_NONE;
return ret;
}
+
+int mc_db_remove_playlist(void *handle, const char *server_name)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ char *sql_str = NULL;
+
+ mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+ mc_retvm_if(server_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "server_name is NULL");
+
+ sql_str = sqlite3_mprintf("DELETE FROM '%q' WHERE server_name='%q';", MC_DB_TABLE_PLAYLIST, server_name);
+
+ ret = __mc_db_update_db(handle, sql_str);
+
+ SQLITE3_SAFE_FREE(sql_str);
+
+ return ret;
+}
+
+int mc_db_update_playlist(void *handle, const char *server_name, const char *playlist_name, bundle *data)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ char *sql_str = NULL;
+ const char *db_fields = "server_name, playlist_name, data, data_size";
+ bundle_raw *raw_data = NULL;
+ int size_r = 0;
+
+ mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+ mc_retvm_if(server_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "server_name is NULL");
+ mc_retvm_if(playlist_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "playlist_name is NULL");
+
+ if (data != NULL) {
+ ret = bundle_encode(data, &raw_data, &size_r);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail while encoding bundle [%d]", ret);
+ }
+
+ sql_str = sqlite3_mprintf("INSERT INTO '%q' (%q) VALUES (%Q, %Q, %Q, %d);", MC_DB_TABLE_PLAYLIST, db_fields, server_name, playlist_name, raw_data, size_r);
+
+ ret = __mc_db_update_db(handle, sql_str);
+
+ SQLITE3_SAFE_FREE(sql_str);
+
+ return ret;
+}
return MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER;
}
- mc_info("type [%d], message [%s]", type, request_msg);
+ mc_secure_debug("type [%d], message [%s]", type, request_msg);
mc_comm_msg_s send_msg;
memset((void *)&send_msg, 0, sizeof(mc_comm_msg_s));
return MEDIA_CONTROLLER_ERROR_NONE;
}
-static int __mc_server_send_message(media_controller_server_s *mc_server, const char *interface_name, const char *signal_name, int param1, unsigned long long param2)
+static int __mc_server_send_message(media_controller_server_s *mc_server, const char *interface_name, const char *signal_name, int param1, unsigned long long param2, const char* param3)
{
int ret = MEDIA_CONTROLLER_ERROR_NONE;
char *message = NULL;
message = g_strdup_printf("%s%s%d%s%llu", mc_server->server_name, MC_STRING_DELIMITER, param1, MC_STRING_DELIMITER, param2);
else if (!g_strcmp0(MC_DBUS_SIGNAL_NAME_METADATA, signal_name))
message = g_strdup_printf("%s", mc_server->server_name);
+ else if (!g_strcmp0(MC_DBUS_SIGNAL_NAME_PLAYLIST, signal_name))
+ message = g_strdup_printf("%s%s%d%s%s", mc_server->server_name, MC_STRING_DELIMITER, param1, MC_STRING_DELIMITER, param3);
else
message = g_strdup_printf("%s%s%d", mc_server->server_name, MC_STRING_DELIMITER, param1);
return ret;
}
- ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAY_BACK, mc_server->playback.state, mc_server->playback.position);
+ ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAY_BACK, mc_server->playback.state, mc_server->playback.position, NULL);
if (ret != MEDIA_CONTROLLER_ERROR_NONE)
mc_error("Error __mc_server_send_message [%d]", ret);
ret = mc_db_update_shuffle_mode(mc_server->db_handle, mc_server->server_name, mode);
mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to mc_db_update_shuffle_mode");
- ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYBACK_SHUFFLE, mode, 0);
+ ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYBACK_SHUFFLE, mode, 0, NULL);
mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
return ret;
ret = mc_db_update_repeat_mode(mc_server->db_handle, mc_server->server_name, mode);
mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to mc_db_update_repeat_mode");
- ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYBACK_REPEAT, mode, 0);
+ ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYBACK_REPEAT, mode, 0, NULL);
mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
return ret;
mc_server->metadata->description, mc_server->metadata->track_num, mc_server->metadata->picture);
mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to mc_db_update_whole_metadata");
- ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_METADATA, 0, 0);
+ ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_METADATA, 0, 0, NULL);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
+
+ return ret;
+}
+
+int mc_server_update_playlist(mc_server_h server, mc_playlist_update_mode_e mode, const char *playlist_name, bundle *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, "invalid server");
+ mc_retvm_if(!MC_STRING_VALID(playlist_name), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "invalid playlist_name");
+
+ ret = mc_db_remove_playlist(mc_server->db_handle, mc_server->server_name);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to mc_db_remove_playlist");
+
+ if (mode == MC_PLAYLIST_UPDATED) {
+ ret = mc_db_update_playlist(mc_server->db_handle, mc_server->server_name, playlist_name, data);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to mc_db_update_playlist");
+ }
+
+ ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST, mode, 0, playlist_name);
mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
return ret;
return ret;
}
- ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SERVER_STATE, MC_SERVER_STATE_ACTIVATE, 0);
+ ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SERVER_STATE, MC_SERVER_STATE_ACTIVATE, 0, NULL);
if (ret != MEDIA_CONTROLLER_ERROR_NONE)
mc_error("Error __mc_server_send_message [%d]", ret);
mc_error("fail mc_db_delete_server_table [%d]", ret);
}
- ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SERVER_STATE, MC_SERVER_STATE_DEACTIVATE, 0);
+ ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SERVER_STATE, MC_SERVER_STATE_DEACTIVATE, 0, NULL);
if (ret != MEDIA_CONTROLLER_ERROR_NONE)
mc_error("Error __mc_server_send_message [%d]", ret);
#define MC_DB_TABLE_SERVER_LIST "server_list"
#define MC_DB_TABLE_LATEST_SERVER "latest_server"
+#define MC_DB_TABLE_PLAYLIST "server_playlist"
+#define MC_DB_TRIGGER_PLAYLIST "cleanup_playlist"
#define DB_SELECT_ALL_SERVER_LIST_EXCEPT_LATEST "SELECT name FROM SQLITE_MASTER WHERE type='table' AND (name != '%q') AND (name NOT IN (SELECT server_name FROM "MC_DB_TABLE_LATEST_SERVER"));"
#define DB_SELECT_LATEST_SERVER "SELECT COUNT(*), server_name FROM "MC_DB_TABLE_LATEST_SERVER";"
return ret;
}
+static int __mc_create_playlist_table(sqlite3 *handle)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ char *sql_str = NULL;
+
+ sql_str = sqlite3_mprintf("CREATE TABLE IF NOT EXISTS %s (\
+ server_name TEXT PRIMARY KEY, \
+ playlist_name TEXT NOT NULL, \
+ data TEXT, \
+ data_size INT);",
+ MC_DB_TABLE_PLAYLIST);
+
+ ret = mc_db_util_update_db(handle, sql_str);
+ SQLITE3_SAFE_FREE(sql_str);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to create playlist table");
+
+ sql_str = sqlite3_mprintf("CREATE TRIGGER IF NOT EXISTS %s DELETE ON %s BEGIN DELETE FROM %s WHERE server_name=old.server_name;END",
+ MC_DB_TRIGGER_PLAYLIST, MC_DB_TABLE_SERVER_LIST, MC_DB_TABLE_PLAYLIST);
+
+ ret = mc_db_util_update_db(handle, sql_str);
+ SQLITE3_SAFE_FREE(sql_str);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to create playlist trigger");
+
+ return ret;
+}
+
static char* __mc_get_db_name(uid_t uid)
{
char result_psswd[MC_FILE_PATH_LEN_MAX] = {0, };
ret = __mc_create_server_list_table(db_handle);
mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "create server_list table failed!err= [%d]", ret);
+ ret = __mc_create_playlist_table(db_handle);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "create playlist table failed!err= [%d]", ret);
+
return MEDIA_CONTROLLER_ERROR_NONE;
}
mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
mc_retvm_if(sql_str == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "sql_str is NULL");
- mc_debug("Update query [%s]", sql_str);
+ mc_secure_debug("Update query [%s]", sql_str);
ret = sqlite3_exec(db_handle, sql_str, NULL, NULL, &err_msg);
if (SQLITE_OK != ret) {
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <inttypes.h>
#include <glib.h>
#include <glib/gprintf.h>
mc_debug("[Client:%s] Repeat mode(%d) updated from server[%s]", _client->client_name, mode, server_name);
}
+void _mc_playlist_update_cb(const char *server_name, mc_playlist_update_mode_e mode, const char *playlist_name, bundle *data, void *user_data)
+{
+ media_controller_client_s *_client = (media_controller_client_s *)g_mc_client;
+ mc_debug("[Client:%s] playlist update mode[%d], playlist_name[%s] updated from server[%s]", _client->client_name, mode, playlist_name, server_name);
+}
+
bool _mc_activated_server_cb(const char *server_name, void *user_data)
{
media_controller_client_s *_client = (media_controller_client_s *)g_mc_client;
static gboolean _create()
{
g_print("== create \n");
- int ret;
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
ret = mc_client_create(&g_mc_client);
if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
static gboolean _foreach()
{
g_print("== create \n");
- int ret;
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
ret = mc_client_foreach_server(g_mc_client, _mc_activated_server_cb, NULL);
if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
return TRUE;
}
-static gboolean _set()
+static gboolean _set_callback()
{
- g_print("== set default callback \n");
int ret = TRUE;
+ mc_debug_fenter();
+
ret = mc_client_set_server_update_cb(g_mc_client, _mc_server_state_updated_cb, NULL);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to set param and initialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_server_update_cb [%d]", ret);
ret = mc_client_set_playback_update_cb(g_mc_client, _mc_playback_updated_cb, NULL);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to set param and initialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_playback_update_cb [%d]", ret);
ret = mc_client_set_metadata_update_cb(g_mc_client, _mc_metadata_updated_cb, NULL);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to set param and initialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_metadata_update_cb [%d]", ret);
ret = mc_client_set_shuffle_mode_update_cb(g_mc_client, _mc_shuffle_mode_updated_cb, NULL);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to set param and initialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_shuffle_mode_update_cb [%d]", ret);
ret = mc_client_set_repeat_mode_update_cb(g_mc_client, _mc_repeat_mode_updated_cb, NULL);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to set param and initialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_repeat_mode_update_cb [%d]", ret);
- g_print("==\n");
+ ret = mc_client_set_playlist_update_cb(g_mc_client, _mc_playlist_update_cb, NULL);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_playlist_update_cb [%d]", ret);
+
+ mc_debug_fleave();
return ret;
}
-static gboolean _unset()
+static gboolean _unset_callback()
{
- g_print("== unset callback \n");
- int ret;
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+
+ mc_debug_fenter();
ret = mc_client_unset_server_update_cb(g_mc_client);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to deinitialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_server_update_cb [%d]", ret);
ret = mc_client_unset_playback_update_cb(g_mc_client);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to deinitialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_playback_update_cb [%d]", ret);
ret = mc_client_unset_metadata_update_cb(g_mc_client);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to deinitialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_metadata_update_cb [%d]", ret);
ret = mc_client_unset_shuffle_mode_update_cb(g_mc_client);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to deinitialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_shuffle_mode_update_cb [%d]", ret);
ret = mc_client_unset_repeat_mode_update_cb(g_mc_client);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to deinitialize %d", ret);
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_repeat_mode_update_cb [%d]", ret);
+
+ ret = mc_client_unset_playlist_update_cb(g_mc_client);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_playlist_update_cb [%d]", ret);
- g_print("== success destroy \n");
+ mc_debug_fleave();
return TRUE;
}
+void __playlist_get_info_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+ void **array_val = NULL;
+ unsigned int array_len = 0;
+ size_t *array_elem_size = NULL;
+ unsigned int idx = 0;
+
+ printf("Key:%s, Type:%d\n", key, type);
+
+ if (bundle_keyval_type_is_array((bundle_keyval_t *)kv)) {
+ ret = bundle_keyval_get_array_val((bundle_keyval_t *)kv, &array_val, &array_len, &array_elem_size);
+ if (ret != BUNDLE_ERROR_NONE) {
+ printf("Fail to bundle_keyval_type_is_array [%d]\n", ret);
+ return;
+ }
+
+ printf("array_len [%d]\n", array_len);
+
+ for (idx = 0; idx < array_len; idx++) {
+ printf("[%d] [%s][%zu]\n", idx, (char *)array_val[idx], array_elem_size[idx]);
+ }
+ } else {
+ printf("Wrong Type\n");
+ }
+}
+
static gboolean _get_info(int type)
{
- g_print("== get information \n");
- int ret;
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
mc_server_state_e server_state;
mc_playback_h playback;
mc_playback_states_e playback_state;
char *metadata_value;
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();
switch (type) {
case 1:
ret = mc_client_get_latest_server_info(g_mc_client, &g_server_name, &server_state);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to get latest server info");
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_latest_server_info [%d]", ret);
+
g_print("get server name: %s, state: %d", g_server_name, server_state);
+
break;
case 2:
ret = mc_client_get_server_playback_info(g_mc_client, g_server_name, &playback);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to get playback info");
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_playback_info [%d]", ret);
+
ret = mc_client_get_playback_state(playback, &playback_state);
if (ret != MEDIA_CONTROLLER_ERROR_NONE)
g_print("Fail to get playback state");
g_print("playback state: %d, position: %lld", playback_state, playback_position);
ret = mc_client_destroy_playback(playback);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to destroy playback");
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_destroy_playback [%d]", ret);
+
break;
case 3:
ret = mc_client_get_server_metadata(g_mc_client, g_server_name, &metadata);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to get metadata");
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_metadata [%d]", ret);
+
ret = mc_client_get_metadata(metadata, MC_META_MEDIA_TITLE, &metadata_value);
if (ret != MEDIA_CONTROLLER_ERROR_NONE)
g_print("Fail to get infot");
g_print("metadata title: %s", metadata_value);
- ret = mc_client_destroy_metadata(metadata);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to destroy metadata");
- return FALSE;
- }
free(metadata_value);
+
+ ret = mc_client_destroy_metadata(metadata);
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_destroy_metadata [%d]", ret);
+
break;
case 4:
ret = mc_client_get_server_shuffle_mode(g_mc_client, g_server_name, &shuffle_mode);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to get infot");
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_shuffle_mode [%d]", ret);
+
g_print("shuffle mode: %d", shuffle_mode);
break;
case 5:
ret = mc_client_get_server_repeat_mode(g_mc_client, g_server_name, &repeate_mode);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- g_print("Fail to get infot");
- return FALSE;
- }
+ mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_repeat_mode [%d]", ret);
+
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);
+ 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);
+
+ bundle_foreach(playlist, __playlist_get_info_cb, NULL);
+
+ bundle_free(playlist);
+ } else {
+ g_print("There is no playlist \n");
+ }
+
+ MC_SAFE_FREE(playlist_name);
+
break;
default:
g_print("== unknown type!\n");
return TRUE;
}
- g_print("== success get information \n");
+ mc_debug_fleave();
return TRUE;
}
static gboolean _destroy()
{
- g_print("== destroy \n");
- int ret;
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+
+ mc_debug_fenter();
ret = mc_client_destroy(g_mc_client);
if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
return FALSE;
}
- g_print("== success destroy \n");
g_mc_client = NULL;
+
+ mc_debug_fleave();
+
return TRUE;
}
g_print("2. get latest server playback \n");
g_print("3. get latest server metadata \n");
g_print("4. get latest server shuffle mode \n");
- g_print("5. get latest server repeate moder \n");
+ g_print("5. get latest server repeate mode \n");
+ g_print("6. get playlist \n");
g_print("0. back \n");
g_print("----------------------------------------------------\n");
g_print("====================================================\n");
_get_info(4);
else if (!strncmp(cmd, "5", len))
_get_info(5);
+ else if (!strncmp(cmd, "6", len))
+ _get_info(6);
else if (!strncmp(cmd, "0", len))
reset_current_menu_state();
+ else
+ g_print("wrong command [%s] \n", cmd);
} else {
g_print("wrong command\n");
}
else if (!strncmp(cmd, "2", len))
_foreach();
else if (!strncmp(cmd, "3", len))
- _set();
+ _set_callback();
else if (!strncmp(cmd, "4", len))
- _unset();
+ _unset_callback();
else if (!strncmp(cmd, "5", len))
g_menu_state = CURRENT_STATE_INFORMATION_GET_MENU;
else if (!strncmp(cmd, "6", len))
#include <glib.h>
#include <glib/gprintf.h>
-#include <media_controller_client.h>
+#include <bundle.h>
+#include <media_controller_server.h>
#include "media_controller_private.h"
-#define PACKAGE "media_controller_client_test"
-
/*===========================================================================================
| |
| LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE |
static int g_metadata_type;
static mc_shuffle_mode_e g_shuffle_mode;
static mc_repeat_mode_e g_repeat_mode;
+static mc_playlist_update_mode_e g_playlist_mode;
GMainLoop *mainloop = NULL;
g_free(bundle_data);
}
+static int __update_playlist(mc_server_h server, mc_playlist_update_mode_e mode)
+{
+ int ret = MEDIA_CONTROLLER_ERROR_NONE;
+
+ const char *playlist_name = "test_playlist";
+ bundle * bundle_data = NULL;
+
+ unsigned int meta_cnt = MC_META_MEDIA_PICTURE + 1;
+ const char *idx_1[meta_cnt];
+ const char *idx_2[meta_cnt];
+ const char *idx_3[meta_cnt];
+
+ memset(idx_1, 0, sizeof(idx_1));
+ memset(idx_2, 0, sizeof(idx_2));
+ memset(idx_3, 0, sizeof(idx_3));
+
+ g_print("== Start __update_playlist [%d] \n", meta_cnt);
+
+ idx_1[MC_META_MEDIA_TITLE] = "title_1";
+ idx_1[MC_META_MEDIA_ARTIST] = "artist_1";
+ idx_1[MC_META_MEDIA_ALBUM] = "album_1";
+ idx_1[MC_META_MEDIA_AUTHOR] = "author_1";
+ idx_1[MC_META_MEDIA_GENRE] = "genre_1";
+ idx_1[MC_META_MEDIA_DURATION] = "duration_1";
+ idx_1[MC_META_MEDIA_DATE] = "date_1";
+ idx_1[MC_META_MEDIA_COPYRIGHT] = "copyright_1";
+ idx_1[MC_META_MEDIA_DESCRIPTION] = "destription_1";
+ idx_1[MC_META_MEDIA_TRACK_NUM] = "track_num_1";
+ idx_1[MC_META_MEDIA_PICTURE] = "picture_1";
+
+ idx_2[MC_META_MEDIA_TITLE] = "title_2";
+ idx_2[MC_META_MEDIA_ARTIST] = "artist_2";
+ idx_2[MC_META_MEDIA_ALBUM] = "album_2";
+ idx_2[MC_META_MEDIA_AUTHOR] = "author_2";
+ idx_2[MC_META_MEDIA_GENRE] = "genre_2";
+ idx_2[MC_META_MEDIA_DURATION] = "duration_2";
+ idx_2[MC_META_MEDIA_DATE] = "date_2";
+ idx_2[MC_META_MEDIA_COPYRIGHT] = "copyright_2";
+// idx_2[MC_META_MEDIA_DESCRIPTION] = NULL;
+ idx_2[MC_META_MEDIA_TRACK_NUM] = "track_num_2";
+// idx_2[MC_META_MEDIA_PICTURE] = NULL;
+
+ idx_3[MC_META_MEDIA_TITLE] = "title_3";
+ idx_3[MC_META_MEDIA_ARTIST] = "artist_3";
+ idx_3[MC_META_MEDIA_ALBUM] = "album_3";
+ idx_3[MC_META_MEDIA_AUTHOR] = "author_3";
+ idx_3[MC_META_MEDIA_GENRE] = "genre_3";
+ idx_3[MC_META_MEDIA_DURATION] = "duration_3";
+ idx_3[MC_META_MEDIA_DATE] = NULL;
+ idx_3[MC_META_MEDIA_COPYRIGHT] = "copyright_3";
+ idx_3[MC_META_MEDIA_DESCRIPTION] = NULL;
+ idx_3[MC_META_MEDIA_TRACK_NUM] = "track_num_3";
+ idx_3[MC_META_MEDIA_PICTURE] = NULL;
+
+ bundle_data = bundle_create();
+ bundle_add_str_array(bundle_data, "idx1", idx_1, meta_cnt);
+ bundle_add_str_array(bundle_data, "idx2", idx_2, meta_cnt);
+ bundle_add_str_array(bundle_data, "idx3", idx_3, meta_cnt);
+
+ ret = mc_server_update_playlist(server, mode, playlist_name, bundle_data);
+
+ bundle_free(bundle_data);
+
+ g_print("== Success __update_playlist \n");
+
+ return ret;
+}
+
static gboolean _create()
{
g_print("== create \n");
return FALSE;
}
break;
+ case 5:
+ if (g_playlist_mode == MC_PLAYLIST_UPDATED)
+ g_playlist_mode = MC_PLAYLIST_REMOVED;
+ else
+ g_playlist_mode = MC_PLAYLIST_UPDATED;
+
+ ret = __update_playlist(g_mc_server, g_playlist_mode);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ g_print("Fail to update playlist err=%d\n", ret);
+ return FALSE;
+ }
+ break;
default:
g_print(" == unknown type!\n");
return TRUE;
g_print("1. update server playback \n");
g_print("2. update server metadata \n");
g_print("3. update server shuffle mode \n");
- g_print("4. update server repeate moder \n");
+ g_print("4. update server repeate mode \n");
+ g_print("5. update playlist \n");
g_print("0. back \n");
g_print("----------------------------------------------------\n");
g_print("====================================================\n");
_update_info(3);
else if (!strncmp(cmd, "4", len))
_update_info(4);
+ else if (!strncmp(cmd, "5", len))
+ _update_info(5);
else if (!strncmp(cmd, "0", len))
reset_current_menu_state();
} else {
_destroy();
else if (!strncmp(cmd, "0", len))
quit();
+ else
+ g_print("wrong command [%s]\n", cmd);
} else {
g_print("wrong command\n");
}
g_shuffle_mode = MC_SHUFFLE_MODE_OFF;
g_repeat_mode = MC_REPEAT_MODE_OFF;
+ g_playlist_mode = MC_PLAYLIST_REMOVED;
mainloop = g_main_loop_new(NULL, FALSE);