[ACR-1293] Add the playback content type, the capability and the icon uri for media... 27/186827/33 accepted/tizen/unified/20180831.061643 submit/tizen/20180830.082244
authorjiyong.min <jiyong.min@samsung.com>
Thu, 16 Aug 2018 00:47:16 +0000 (09:47 +0900)
committerhj kim <backto.kim@samsung.com>
Thu, 30 Aug 2018 08:13:16 +0000 (17:13 +0900)
Change-Id: Ic14a66c70b0ba574182b6c205137e138e1ea60b6

14 files changed:
doc/media_controller_doc.h
include/media_controller_client.h
include/media_controller_db.h
include/media_controller_metadata.h
include/media_controller_private.h
include/media_controller_server.h
include/media_controller_type.h
src/media_controller_client.c
src/media_controller_db.c
src/media_controller_metadata.c
src/media_controller_server.c
svc/media_controller_db_util.c [changed mode: 0755->0644]
test/client_test/media_controller_client_test.c
test/server_test/media_controller_server_test.c

index 12c98577b8e7f5eb514b381685f4b1702f6b6aee..664224d8cb7126cca38b538ca3380ad5b14b720f 100755 (executable)
 *
 */
 
+/**
+* @ingroup CAPI_MEDIA_CONTROLLER_MODULE
+* @defgroup CAPI_MEDIA_CONTROLLER_ABILITY_MODULE Media Controller Playback ability
+* @brief The @ref CAPI_MEDIA_CONTROLLER_ABILITY_MODULE API provides functions for the playback ability fo the media controller server.
+* @section CAPI_MEDIA_CONTROLLER_ABILITY_MODULE_HEADER Required Header
+*      \#include <media_controller_client.h>
+*
+* @section CAPI_MEDIA_CONTROLLER_ABILITY_MODULE_OVERVIEW Overview
+* The @ref CAPI_MEDIA_CONTROLLER_ABILITY_MODULE API allows you to get playback action ability (#mc_playback_action_is_supported()). \n
+* You can copy the ability by using #mc_playback_ability_clone(). And if you don't use handle anymore, you have to destroy it(#mc_playback_ability_destroy()).
+*
+*/
+
 
 #endif /* __TIZEN_MEDIA_CONTROLLER_DOC_H__ */
 
index d3b66168f678dcdac1110734f95882dcc06542f4..75df8bca7b54bd191e023e4825ee09c2e5538525 100755 (executable)
@@ -87,7 +87,7 @@ typedef void (*mc_playback_updated_cb)(const char *server_name, mc_playback_h pl
  *               And @a metadata also can be used only in the callback. To use outside, make a copy using mc_metadata_clone() \n
  *
  * @param[in] server_name The app_id of the media controller server which sent the notification.
- * @param[in] metadata the metadata of the updated media controller server.
+ * @param[in] metadata The metadata of the updated media controller server.
  * @param[in] user_data        The user data passed from the mc_client_set_metadata_updated_cb() function
  *
  * @pre mc_client_set_metadata_updated_cb()
@@ -167,6 +167,64 @@ typedef void (*mc_shuffle_mode_updated_cb)(const char *server_name, mc_shuffle_m
  */
 typedef void (*mc_repeat_mode_updated_cb)(const char *server_name, mc_repeat_mode_e mode, void *user_data);
 
+/**
+ * @brief Called when updating the playback ability of the media controller server.
+ * @since_tizen 5.0
+ *
+ * @remarks The callback is called in the dbus event loop.
+ *               The @a server_name should not be released by the application. \n
+ *               The @a server_name can be used only in the callback. To use outside, make a copy.
+ *               And @a ability also can be used only in the callback. To use outside, make a copy using mc_playback_ability_clone() \n
+ *
+ * @param[in] server_name The app_id of the media controller server which sent the notification
+ * @param[in] ability The ability of the updated media controller server
+ * @param[in] user_data        The user data passed from the mc_client_set_playback_ability_updated_cb() function
+ *
+ * @pre mc_client_set_playback_ability_updated_cb()
+ *
+ * @see mc_client_set_playback_ability_updated_cb()
+ * @see mc_playback_action_is_supported()
+ */
+typedef void (*mc_playback_ability_updated_cb)(const char *server_name, mc_playback_ability_h ability, void *user_data);
+
+/**
+ * @brief Called when updating the shuffle ability of the media controller server.
+ * @since_tizen 5.0
+ *
+ * @remarks The callback is called in the dbus event loop.
+ *               The @a server_name should not be released by the application. \n
+ *               The @a server_name 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
+ * @param[in] support The support value of the ability of the updated media controller server
+ * @param[in] user_data        The user data passed from the mc_client_set_shuffle_ability_updated_cb() function
+ *
+ * @pre mc_client_set_shuffle_ability_updated_cb()
+ *
+ * @see mc_client_set_shuffle_ability_updated_cb()
+ */
+typedef void (*mc_shuffle_ability_updated_cb)(const char *server_name, mc_ability_support_e support, void *user_data);
+
+/**
+ * @brief Called when updating the repeat ability of the media controller server.
+ * @since_tizen 5.0
+ *
+ * @remarks The callback is called in the dbus event loop.
+ *               The @a server_name should not be released by the application. \n
+ *               The @a server_name 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
+ * @param[in] support The support value of the ability of the updated media controller server
+ * @param[in] user_data        The user data passed from the mc_client_set_repeat_ability_updated_cb() function
+ *
+ * @pre mc_client_set_repeat_ability_updated_cb()
+ *
+ * @see mc_client_set_repeat_ability_updated_cb()
+ */
+
+typedef void (*mc_repeat_ability_updated_cb)(const char *server_name, mc_ability_support_e support, void *user_data);
+
+
 /**
  * @brief Called when requesting the list of created servers.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
@@ -733,6 +791,129 @@ int mc_client_set_repeat_mode_updated_cb(mc_client_h client, mc_repeat_mode_upda
  */
 int mc_client_unset_repeat_mode_updated_cb(mc_client_h client);
 
+/**
+ * @brief Sets the callback for monitoring the playback ability 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 ability 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_playback_ability_updated_cb(mc_client_h client, mc_playback_ability_updated_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the callback for monitoring the playback ability 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_playback_ability_updated_cb(mc_client_h client);
+
+/**
+ * @brief Sets the callback for monitoring the shuffle ability 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 ability 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_shuffle_ability_updated_cb(mc_client_h client, mc_shuffle_ability_updated_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the callback for monitoring the shuffle ability 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_shuffle_ability_updated_cb(mc_client_h client);
+
+/**
+ * @brief Sets the callback for monitoring the repeat ability 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 ability 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_repeat_ability_updated_cb(mc_client_h client, mc_repeat_ability_updated_cb callback, void *user_data);
+
+/**
+ * @brief Unsets the callback for monitoring the repeat ability 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_repeat_ability_updated_cb(mc_client_h client);
+
 /**
  * @brief Sets the callback for receiving the result of the command from the media controller server.
  * @details The media controller client which calls this function will receives the result of the command from all media controller servers.
@@ -1040,6 +1221,26 @@ int mc_client_get_playback_position(mc_playback_h playback, unsigned long long *
  */
 int mc_client_get_playlist_item_index(mc_playback_h playback, char **index);
 
+/**
+ * @brief Gets the playback content type.
+ * @details Gets the content type of the current playing media. If there is no content type info, result value is #MC_CONTENT_TYPE_UNDECIDED.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @param[in] playback    The handle to playback
+ * @param[out] content_type    The content type of the playback
+ * @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 The playback update callback should be set with mc_client_set_playback_updated_cb().
+ * @see mc_client_set_playback_updated_cb()
+ */
+int mc_client_get_playback_content_type(mc_playback_h playback, mc_content_type_e *content_type);
+
 /**
  * @brief Destroys playback.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
@@ -1202,6 +1403,114 @@ int mc_client_get_server_shuffle_mode(mc_client_h client, const char *server_nam
  */
 int mc_client_get_server_repeat_mode(mc_client_h client, const char *server_name, mc_repeat_mode_e *mode);
 
+/**
+ * @brief Gets the icon URI of the media controller server.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @remarks The @a uri should be released using @c free(). \n
+ *                   If there is no URI info, return value of the uri 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] uri    The icon URI
+ * @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 Out of memory
+ * @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()
+ * @see mc_client_foreach_server_playlist()
+ */
+int mc_client_get_server_icon(mc_client_h client, const char *server_name, char **uri);
+
+/**
+ * @brief Gets the playback ability of the media controller server.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @remarks The @a ability should be released using @c mc_playback_ability_destroy().
+ *
+ * @param[in] client The handle to the media controller client
+ * @param[in] server_name    The app_id of the media controller server
+ * @param[out] ability    The handle to ability
+ * @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 Out of memory
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller client handle by calling mc_client_create().
+ * @pre Get a server name handle by calling mc_client_create().
+ * @see mc_client_create()
+ * @see mc_client_destroy()
+ * @see mc_client_get_latest_server_info()
+ * @see mc_client_foreach_server()
+ * @see mc_playback_action_is_supported()
+ */
+int mc_client_get_server_playback_ability(mc_client_h client, const char *server_name, mc_playback_ability_h *ability);
+
+/**
+ * @brief Gets the support value of the shuffle ability of the updated media controller server.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @remarks If the ability's support is not set, the result value is #MC_ABILITY_SUPPORTED_UNDECIDED.
+ *
+ * @param[in] client The handle to the media controller client
+ * @param[in] server_name    The app_id of the media controller server
+ * @param[out] support    The support value of the shuffle ability
+ * @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 Out of memory
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller client handle by calling mc_client_create().
+ * @pre Get a server name handle by calling mc_client_create().
+ * @see mc_client_create()
+ * @see mc_client_destroy()
+ * @see mc_client_get_latest_server_info()
+ * @see mc_client_foreach_server()
+ */
+int mc_client_get_server_shuffle_ability_support(mc_client_h client, const char *server_name, mc_ability_support_e *support);
+
+/**
+ * @brief Gets the support value of the repeat ability of the updated media controller server.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.client
+ *
+ * @remarks If the ability's support is not set, the result value is #MC_ABILITY_SUPPORTED_UNDECIDED.
+ *
+ * @param[in] client The handle to the media controller client
+ * @param[in] server_name    The app_id of the media controller server
+ * @param[out] support    The support value of the repeat ability
+ * @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 Out of memory
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller client handle by calling mc_client_create().
+ * @pre Get a server name handle by calling mc_client_create().
+ * @see mc_client_create()
+ * @see mc_client_destroy()
+ * @see mc_client_get_latest_server_info()
+ * @see mc_client_foreach_server()
+ */
+int mc_client_get_server_repeat_ability_support(mc_client_h client, const char *server_name, mc_ability_support_e *support);
+
 /**
  * @brief Retrieves all created servers.
  * @details This function gets all created media controller servers.
index f791ed10b9e674fc30716026612f1638d569e496..8a46dc943c24a61e2ba48fce133fc9d395bdf39d 100755 (executable)
@@ -26,12 +26,14 @@ int mc_db_delete_server_table(void *handle, const char *server_name);
 int mc_db_check_server_table_exist(void *handle, const char *server_name, bool *exist);
 int mc_db_check_client_table_exist(void *handle, const char *client_name, bool *exist);
 
-int mc_db_update_playback_info(void *handle, const char *table_name, int playback_state, unsigned long long playback_position, const char *index);
+int mc_db_update_playback_info(void *handle, const char *table_name, const media_controller_playback_s playback);
 int mc_db_update_whole_metadata(void *handle, const char *server_name,
                                                const char *title, const char *artist, const char *album, const char *author, const char *genre, const char *duration, const char *date,
                                                const char *copyright, const char *description, const char *track_num, const char *picture);
 int mc_db_update_shuffle_mode(void *handle, const char *table_name, int shuffle_mode);
 int mc_db_update_repeat_mode(void *handle, const char *table_name, int repeat_mode);
+int mc_db_update_icon_uri(void *handle, const char *server_name, const char *uri);
+int mc_db_update_ability_supported(void *handle, const char *server_name, const media_controller_ability_s ability);
 int mc_db_update_extra_info(void *handle, const char *server_name, const char *event_name, const char *extras);
 
 int mc_db_get_latest_server_name(void *handle, char **latest_server_name);
@@ -40,6 +42,9 @@ int mc_db_get_playback_info(void *handle, const char *server_name, mc_playback_h
 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_icon_uri(void *handle, const char *server_name, char **uri);
+int mc_db_get_ability_supported(void *handle, const char *server_name, mc_ability_e ability, mc_ability_support_e *supported);
+int mc_db_get_pb_action_ability(void *handle, const char *server_name, mc_playback_ability_h *ability);
 int mc_db_get_foreach_playlist(void *handle, const char *server_name, mc_playlist_cb callback, void *user_data);
 int mc_db_get_playlist_item(void *handle, const char *server_name, char *playlist_name, mc_playlist_item_cb callback, void *user_data);
 int mc_db_insert_server_address_into_server_list(void *db_handle, const char *address);
index 153ad1886bb994a97fb1b48b2261876555f91144..888d9e6e9dd77fc493294b8cfa0bf8508cc45333 100755 (executable)
@@ -24,16 +24,17 @@ extern "C" {
 #endif /* __cplusplus */
 
 
-/**
- * @addtogroup CAPI_MEDIA_CONTROLLER_METADATA_MODULE
- * @{
- */
 
 /**
  * @file media_controller_metadata.h
  * @brief This file contains the media controller metadata API and functions related with handling media control.
  */
 
+/**
+ * @addtogroup CAPI_MEDIA_CONTROLLER_METADATA_MODULE
+ * @{
+ */
+
 /**
  * @brief Clones a media controller metadata handle.
  * @details This function copies the media controller metadata handle from a source to
@@ -107,6 +108,82 @@ int mc_metadata_get(mc_metadata_h metadata, mc_meta_e attribute, char **value);
 * @}
 */
 
+/**
+ * @addtogroup CAPI_MEDIA_CONTROLLER_ABILITY_MODULE
+ * @{
+ */
+
+/**
+ * @brief Clones a playback ability handle.
+ * @details This function copies the playback ability handle from a source to
+ *          destination. The mc_playback_ability_h is created internally and available through playback ability functions.
+ *
+ * @since_tizen 5.0
+ *
+ * @remarks The @a dst should be released using @c mc_playback_ability_destroy().
+ *
+ * @param[in] src The source handle to the playback ability
+ * @param[out] dst The destination handle to the playback ability
+ *
+ * @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 Out of memory
+ *
+ * @see mc_playback_ability_destroy()
+ */
+int mc_playback_ability_clone(mc_playback_ability_h src, mc_playback_ability_h *dst);
+
+/**
+ * @brief Destroys a playback ability handle.
+ * @details This function frees all resources related to the playback ability handle. This
+ *          handle no longer can be used to perform any operations. A new handle has to
+ *          be created before next use.
+ *
+ * @since_tizen 5.0
+ *
+ * @param[in] ability        The handle to the playback ability
+ *
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ *
+ * @retval #MEDIA_CONTROLLER_ERROR_NONE Successful
+ * @retval #MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see mc_playback_ability_clone()
+ */
+int mc_playback_ability_destroy(mc_playback_ability_h ability);
+
+/**
+ * @brief Gets the support value of the playback ability.
+ * @since_tizen 5.0
+ *
+ * @remarks If the ability's support is not set, the result value is #MC_ABILITY_SUPPORTED_UNDECIDED.
+ *
+ * @param[in] ability    The handle to ability
+ * @param[in] action    The playback action to get
+ * @param[out] supported      The support value of the ability
+ *
+ * @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 Out of memory
+ *
+ * @pre Call the mc_client_set_playback_ability_updated_cb() function to get the ability if you are the media controller client.
+ *
+ * @see mc_client_set_playback_ability_updated_cb()
+ * @see mc_client_get_server_playback_ability()
+ */
+int mc_playback_action_is_supported(mc_playback_ability_h ability, mc_playback_action_e action, mc_ability_support_e *supported);
+
+/**
+* @}
+*/
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 23e1152c977f7ee28d33f02f575c0874c9f3e69d..6c475e039ef5146a84e1709111946fe5e9823eba 100755 (executable)
@@ -171,6 +171,11 @@ extern "C" {
 #define MC_DBUS_SIGNAL_NAME_CUSTOM_COMMAND_REPLY       "custom_command_reply"
 #define MC_DBUS_SIGNAL_NAME_CUSTOM_EVENT                       "custom_event"
 #define MC_DBUS_SIGNAL_NAME_EVENT_REPLY                                "event_reply"
+#define MC_DBUS_SIGNAL_NAME_PLAYBACK_ABILITY                   "playback_ability"
+#define MC_DBUS_SIGNAL_NAME_SHUFFLE_ABILITY                    "shuffle_ability"
+#define MC_DBUS_SIGNAL_NAME_REPEAT_ABILITY                     "repeat_ability"
+
+
 
 
 #define MC_COMMAND_PLAYBACKSTATE               "_pb_state_cmd_"
@@ -197,6 +202,8 @@ extern "C" {
 #define MC_DB_CMD_UPDATE_REPEAT                "DB_CMD_UPDATE_REPEAT"                  /* Update Server Repeat mode*/
 #define MC_DB_CMD_UPDATE_LATEST                "DB_CMD_UPDATE_LATEST"                  /* Update Latest Server info*/
 #define MC_DB_CMD_UPDATE_PLAYLIST      "DB_CMD_UPDATE_PLAYLIST"                /* Update Server Playlist*/
+#define MC_DB_CMD_UPDATE_ICON          "DB_CMD_UPDATE_ICON"                    /* Update Server Icon*/
+#define MC_DB_CMD_UPDATE_ABILITY               "DB_CMD_UPDATE_ABILITY"                 /* Update Server abilities*/
 #define MC_DB_CMD_REMOVE_SERVER                "DB_CMD_REMOVE_SERVER"          /* Remove Server info*/
 #define MC_DB_CMD_REMOVE_PLAYLIST      "DB_CMD_REMOVE_PLAYLIST"                /* Remove Server State*/
 #define MC_DB_CMD_REMOVE_SERVER_LIST   "DB_CMD_REMOVE_SERVER_LIST"     /* Remove Server from Server List*/
@@ -220,6 +227,21 @@ extern "C" {
                } \
        } while (0)
 
+#define MC_BIT64_UNSET         0x0000000000000000
+#define MC_BIT64_SET           0x0000000000000001
+#define MC_BIT64_IS_OK(x)      ((x < 64) ? TRUE : FALSE)
+#define MC_BIT64_IS_TRUE(a, b) (((a >> b) & MC_BIT64_SET) ? TRUE : FALSE)
+#define MC_BIT64_SET_BIT(a, b) \
+       do { \
+               if (MC_BIT64_IS_OK(b)) \
+                       (a |= ((MC_BIT64_SET << b))); \
+       } while (0)
+#define MC_BIT64_UNSET_BIT(a, b) \
+       do { \
+               if (MC_BIT64_IS_OK(b)) \
+                       (a &= ~((MC_BIT64_SET << b))); \
+       } while (0)
+
 typedef struct {
        void *callback;
        void *user_data;
@@ -230,6 +252,7 @@ typedef struct {
        mc_playback_states_e state;
        unsigned long long position;
        char *index;
+       mc_content_type_e content_type;
 } media_controller_playback_s;
 
 typedef struct {
@@ -246,6 +269,11 @@ typedef struct {
        char *picture;
 } media_controller_metadata_s;
 
+typedef struct {
+       unsigned long long decided;
+       unsigned long long supported;
+} media_controller_ability_s;
+
 typedef struct {
        char *server_name;
        void* db_handle;
@@ -259,6 +287,10 @@ typedef struct {
        media_controller_playback_s playback;
        media_controller_metadata_s *metadata;
 
+       /* ability */
+       media_controller_ability_s basic_ability;
+
+       /* receiver */
        media_controller_receiver_s playback_state_reciever;
        media_controller_receiver_s playback_action_reciever;
        media_controller_receiver_s playback_position_reciever;
@@ -277,6 +309,9 @@ typedef enum {
        MC_EVENT_SHUFFLE                        = MC_SUBSCRIPTION_TYPE_SHUFFLE_MODE,
        MC_EVENT_REPEAT                 = MC_SUBSCRIPTION_TYPE_REPEAT_MODE,
        MC_EVENT_PLAYLIST                       = MC_SUBSCRIPTION_TYPE_PLAYLIST,
+       MC_EVENT_PLAYBACK_ABILITY       = MC_SUBSCRIPTION_TYPE_PLAYBACK_ABILITY,
+       MC_EVENT_SHUFFLE_ABILITY        = MC_SUBSCRIPTION_TYPE_SHUFFLE_ABILITY,
+       MC_EVENT_REPEAT_ABILITY = MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY,
        MC_EVENT_CMD_REPLY,
        MC_EVENT_CLIENT_CUSTOM, //from client to server
        MC_EVENT_SERVER_CUSTOM, //from server to client
@@ -316,6 +351,12 @@ typedef struct {
        char *picture;
 } mc_playlist_item_s;
 
+typedef enum {
+       MC_ABILITY_ACTION = 0,
+       MC_ABILITY_SHUFFLE = 20,
+       MC_ABILITY_REPEAT,
+} mc_ability_e;
+
 /* formal callback to receive signal */
 typedef void(*mc_signal_received_cb)(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
 typedef struct {
index 150218db94fd272c2ba6f4e5e9be2309493f43c7..3722afb9d803d5f72ae528432c6daf1937724a48 100755 (executable)
@@ -349,6 +349,30 @@ int mc_server_set_playback_position(mc_server_h server, unsigned long long posit
  */
 int mc_server_set_playlist_item_index(mc_server_h server, const char *index);
 
+/**
+ * @brief Sets the playback content type to update the latest playback info.
+ * @details If this function is called, the updated content type information will be sent to all clients.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @param[in] server The handle to media controller server
+ * @param[in] content_type The content type to set the latest status
+ * @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 Out of memory
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller server handle by calling mc_server_create().
+ * @post Apply the updated playback information by calling mc_server_update_playback_info().
+ * @see mc_server_create()
+ * @see mc_server_destroy()
+ * @see mc_server_update_playback_info()
+ */
+int mc_server_set_playback_content_type(mc_server_h server, mc_content_type_e content_type);
+
 /**
  * @brief Updates the modified playback info.
  * @details If this function is called, the updated playback information will be sent to the controller.
@@ -1108,6 +1132,116 @@ int mc_server_delete_playlist(mc_server_h server, mc_playlist_h playlist);
  */
 int mc_server_foreach_playlist(mc_server_h server, mc_playlist_cb callback, void *user_data);
 
+/**
+ * @brief Sets the playback ability's support of the media controller.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @param[in] server The handle to media controller server
+ * @param[in] action   The playback action
+ * @param[in] support    The support value of the ability
+ * @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 Out of memory
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller server handle by calling mc_server_create().
+ * @post Update abilities of a media controller server by calling mc_server_update_playback_ability().
+ * @see mc_server_create()
+ * @see mc_server_destroy()
+ */
+int mc_server_set_playback_ability(mc_server_h server, mc_playback_action_e action, mc_ability_support_e support);
+
+/**
+ * @brief Updates the modified ability info.
+ * @details If this function is called, the updated ability will be sent to all clients.
+ * @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_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED Permission denied
+ * @pre Create a media controller server handle by calling mc_server_create().
+ * @pre Set abilities of a media controller server by calling mc_server_set_playback_ability().
+ * @see mc_server_create()
+ * @see mc_server_destroy()
+ */
+int mc_server_update_playback_ability(mc_server_h server);
+
+/**
+ * @brief Sets the shuffle ability's support of the media controller.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @param[in] server The handle to media controller server
+ * @param[in] support    The support value of the ability
+ * @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 Out of memory
+ * @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_shuffle_ability(mc_server_h server, mc_ability_support_e support);
+
+/**
+ * @brief Sets the repeat ability's support of the media controller.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @param[in] server The handle to media controller server
+ * @param[in] support    The support value of the ability
+ * @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 Out of memory
+ * @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_repeat_ability(mc_server_h server, mc_ability_support_e support);
+
+/**
+ * @brief Sets the icon URI of media controller server.
+ * @since_tizen 5.0
+ *
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediacontroller.server
+ *
+ * @remarks It's possible to set URI to NULL if there is no icon.
+ *
+ * @param[in] server The handle to media controller server
+ * @param[in] uri    The icon URI
+ * @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 Out of memory
+ * @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_icon(mc_server_h server, const char *uri);
+
 /**
  * @}
  */
index daea6c2c30ac8da61f54514534171da84f78c5ed..d245cfd0a9e0d3dea08e3defe19031383f1e41d6 100755 (executable)
@@ -65,6 +65,12 @@ typedef void *mc_metadata_h;
  */
 typedef void *mc_playlist_h;
 
+/**
+ * @brief The structure type for the media controller ability handle.
+ * @since_tizen 5.0
+ */
+typedef void *mc_playback_ability_h;
+
 /**
  * @brief Enumeration for the media controller error.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
@@ -170,6 +176,9 @@ typedef enum {
        MC_SUBSCRIPTION_TYPE_SHUFFLE_MODE,                                      /**< Shuffle mode */
        MC_SUBSCRIPTION_TYPE_REPEAT_MODE,                                       /**< Repeat mode */
        MC_SUBSCRIPTION_TYPE_PLAYLIST,                                          /**< Playlist (Since @if MOBILE 4.0 @elseif WEARABLE 5.0 @endif) */
+       MC_SUBSCRIPTION_TYPE_PLAYBACK_ABILITY,                          /**< Playback ability (Since 5.0) */
+       MC_SUBSCRIPTION_TYPE_SHUFFLE_ABILITY,                                   /**< Shuffle ability (Since 5.0) */
+       MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY,                                    /**< Repeat ability (Since 5.0) */
 } mc_subscription_type_e;
 
 /**
@@ -181,6 +190,28 @@ typedef enum {
        MC_PLAYLIST_REMOVED,    /**< Remove playlist */
 } mc_playlist_update_mode_e;
 
+/**
+ * @brief Enumeration for the content type of the media controller server.
+ * @since_tizen 5.0
+ */
+typedef enum {
+       MC_CONTENT_TYPE_IMAGE = 0,      /**< Image content type */
+       MC_CONTENT_TYPE_VIDEO,  /**< Video content type */
+       MC_CONTENT_TYPE_MUSIC,  /**< Music content type */
+       MC_CONTENT_TYPE_OTHER,  /**< Other content type */
+       MC_CONTENT_TYPE_UNDECIDED,      /**< Not decided */
+} mc_content_type_e;
+
+/**
+ * @brief Enumeration for the support of the ability.
+ * @since_tizen 5.0
+ */
+typedef enum {
+       MC_ABILITY_SUPPORTED_YES = 0,           /**< Supported */
+       MC_ABILITY_SUPPORTED_NO,                        /**< Not supported */
+       MC_ABILITY_SUPPORTED_UNDECIDED, /**< Not decided */
+} mc_ability_support_e;
+
 /**
  * @}
  */
index bb4e8af069500fba3a94ad28a8d3f77fd5b573ec..5ed831f4dc3e65caddab9767b5e784f633ec4b34 100755 (executable)
@@ -28,6 +28,10 @@ static void __client_reply_cb(const char *interface_name, const char *signal_nam
 static void __client_playlist_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
 static void __client_cmd_reply_received_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
 static void __client_custom_event_received_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
+static void __client_playback_ability_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
+static void __client_repeat_ability_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
+static void __client_shuffle_ability_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
+
 
 typedef struct {
        const char *signal_name;
@@ -41,6 +45,9 @@ mc_cb_event_s cb_event[MC_EVENT_MAX] = {
        {MC_DBUS_SIGNAL_NAME_PLAYBACK_SHUFFLE,  __client_shuffle_cb},
        {MC_DBUS_SIGNAL_NAME_PLAYBACK_REPEAT,   __client_repeat_cb},
        {MC_DBUS_SIGNAL_NAME_PLAYLIST,                          __client_playlist_cb},
+       {MC_DBUS_SIGNAL_NAME_PLAYBACK_ABILITY,  __client_playback_ability_cb},
+       {MC_DBUS_SIGNAL_NAME_SHUFFLE_ABILITY,           __client_shuffle_ability_cb},
+       {MC_DBUS_SIGNAL_NAME_REPEAT_ABILITY,            __client_repeat_ability_cb},
        {MC_DBUS_SIGNAL_NAME_CMD_REPLY,                 __client_cmd_reply_received_cb},
        {MC_DBUS_SIGNAL_NAME_CUSTOM_COMMAND_REPLY,      __client_reply_cb},
        {MC_DBUS_SIGNAL_NAME_CUSTOM_EVENT,              __client_custom_event_received_cb},
@@ -51,9 +58,9 @@ static void __client_server_cb(const char *interface_name, const char *signal_na
        gchar **params = NULL;
        media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data;
        mc_retm_if(reciever == NULL, "reciever is NULL");
-       mc_server_state_updated_cb callback = (mc_server_state_updated_cb)reciever->callback;
 
-       mc_retm_if(reciever->callback == NULL, "server_state_cb is NULL");
+       mc_server_state_updated_cb callback = (mc_server_state_updated_cb)reciever->callback;
+       mc_retm_if(callback == NULL, "server_state_cb is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
        mc_debug("__client_server_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
@@ -69,12 +76,13 @@ static void __client_server_cb(const char *interface_name, const char *signal_na
 static void __client_playback_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data)
 {
        gchar **params = NULL;
+       media_controller_playback_s *playback = NULL;
+
        media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data;
        mc_retm_if(reciever == NULL, "reciever is NULL");
-       mc_playback_updated_cb callback = (mc_playback_updated_cb)reciever->callback;
-       media_controller_playback_s *playback = NULL;
 
-       mc_retm_if(reciever->callback == NULL, "playback_cb is NULL");
+       mc_playback_updated_cb callback = (mc_playback_updated_cb)reciever->callback;
+       mc_retm_if(callback == NULL, "playback_cb is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
        mc_debug("__client_playback_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
@@ -92,6 +100,7 @@ static void __client_playback_cb(const char *interface_name, const char *signal_
        playback->state = atoi(params[1]);
        playback->position = strtoull(params[2], NULL, 10);
        playback->index = g_strdup(params[3]);
+       playback->content_type = atoi(params[4]);
 
        callback(params[0], (mc_playback_h) playback, reciever->user_data);
 
@@ -104,10 +113,11 @@ static void __client_metadata_cb(const char *interface_name, const char *signal_
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        mc_metadata_h metadata = NULL;
+
        media_controller_client_s *mc_client = (media_controller_client_s *)user_data;
        mc_retm_if(mc_client == NULL, "mc_client is NULL");
-       mc_metadata_updated_cb callback = (mc_metadata_updated_cb)mc_client->updated_cb[MC_EVENT_METADATA].callback;
 
+       mc_metadata_updated_cb callback = (mc_metadata_updated_cb)mc_client->updated_cb[MC_EVENT_METADATA].callback;
        mc_retm_if(callback == NULL, "metadata_cb is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
@@ -127,9 +137,10 @@ static void __client_shuffle_cb(const char *interface_name, const char *signal_n
        gchar **params = NULL;
        media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data;
        mc_retm_if(reciever == NULL, "reciever is NULL");
-       mc_shuffle_mode_changed_cb callback = (mc_shuffle_mode_changed_cb)reciever->callback;
 
-       mc_retm_if(reciever->callback == NULL, "shuffle_cb is NULL");
+       mc_shuffle_mode_changed_cb callback = (mc_shuffle_mode_changed_cb)reciever->callback;
+       mc_retm_if(callback == NULL, "shuffle_cb is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
 
        mc_debug("__client_shuffle_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
 
@@ -146,9 +157,10 @@ static void __client_repeat_cb(const char *interface_name, const char *signal_na
        gchar **params = NULL;
        media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data;
        mc_retm_if(reciever == NULL, "reciever is NULL");
-       mc_repeat_mode_changed_cb callback = (mc_repeat_mode_changed_cb)reciever->callback;
 
-       mc_retm_if(reciever->callback == NULL, "repeat_cb is NULL");
+       mc_repeat_mode_changed_cb callback = (mc_repeat_mode_changed_cb)reciever->callback;
+       mc_retm_if(callback == NULL, "repeat_cb is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
 
        mc_debug("__client_repeat_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
 
@@ -170,7 +182,8 @@ static void __client_reply_cb(const char *interface_name, const char *signal_nam
        mc_retm_if(reciever == NULL, "reciever is NULL");
 
        mc_command_reply_received_cb callback = (mc_command_reply_received_cb)reciever->callback;
-       mc_retm_if(reciever->callback == NULL, "reply_cb is NULL");
+       mc_retm_if(callback == NULL, "reply_cb is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
 
        mc_debug("__client_reply_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
 
@@ -194,8 +207,9 @@ static void __client_playlist_cb(const char *interface_name, const char *signal_
 
        media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data;
        mc_retm_if(reciever == NULL, "reciever is NULL");
+
        mc_playlist_updated_cb callback = (mc_playlist_updated_cb)reciever->callback;
-       mc_retm_if(reciever->callback == NULL, "playlist_cb is NULL");
+       mc_retm_if(callback == NULL, "playlist_cb is NULL");
        mc_retm_if(message == NULL, "message is NULL");
 
        mc_debug("__client_playlist_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
@@ -234,7 +248,8 @@ static void __client_cmd_reply_received_cb(const char *interface_name, const cha
        mc_retm_if(reciever == NULL, "reciever is NULL");
 
        mc_cmd_reply_received_cb callback = (mc_cmd_reply_received_cb)reciever->callback;
-       mc_retm_if(reciever->callback == NULL, "reply_cb is NULL");
+       mc_retm_if(callback == NULL, "reply_cb is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
 
        mc_debug("__client_cmd_reply_received_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
 
@@ -297,6 +312,69 @@ static void __client_custom_event_received_cb(const char *interface_name, const
        g_strfreev(params);
 }
 
+static void __client_playback_ability_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       mc_playback_ability_h ability = NULL;
+
+       media_controller_client_s *mc_client = (media_controller_client_s *)user_data;
+       mc_retm_if(mc_client == NULL, "mc_client is NULL");
+
+       mc_playback_ability_updated_cb callback = (mc_playback_ability_updated_cb)mc_client->updated_cb[MC_EVENT_PLAYBACK_ABILITY].callback;
+       mc_retm_if(callback == NULL, "metadata_cb is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
+
+       mc_debug("__client_playback_ability_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
+
+       ret = mc_db_get_pb_action_ability(mc_client->db_handle, message, &ability);
+       if (ret != MEDIA_CONTROLLER_ERROR_NONE)
+               mc_error("Fail to mc_db_get_pb_action_ability");
+
+       callback(message, ability, mc_client->updated_cb[MC_EVENT_PLAYBACK_ABILITY].user_data);
+
+       mc_playback_ability_destroy(ability);
+}
+
+static void __client_shuffle_ability_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data)
+{
+       gchar **params = NULL;
+       media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data;
+       mc_retm_if(reciever == NULL, "reciever is NULL");
+
+       mc_shuffle_ability_updated_cb callback = (mc_shuffle_ability_updated_cb)reciever->callback;
+       mc_retm_if(callback == NULL, "shuffle_ability_cb is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
+
+       mc_debug("__client_shuffle_ability_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
+
+       params = g_strsplit(message, MC_STRING_DELIMITER, 0);
+       mc_retm_if(params == NULL, "invalid shuffle ability data");
+
+       callback(params[0], (mc_ability_support_e)atoi(params[1]), reciever->user_data);
+
+       g_strfreev(params);
+}
+
+static void __client_repeat_ability_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data)
+{
+       gchar **params = NULL;
+       media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data;
+       mc_retm_if(reciever == NULL, "reciever is NULL");
+
+       mc_repeat_ability_updated_cb callback = (mc_repeat_ability_updated_cb)reciever->callback;
+       mc_retm_if(callback == NULL, "repeat_ability_cb is NULL");
+       mc_retm_if(message == NULL, "message is NULL");
+
+       mc_debug("__client_repeat_ability_cb(%s, %s, %s, %s, %p)", interface_name, signal_name, message, request_id, user_data);
+
+       params = g_strsplit(message, MC_STRING_DELIMITER, 0);
+       mc_retm_if(params == NULL, "invalid repeat ability data");
+
+       callback(params[0], (mc_ability_support_e)atoi(params[1]), reciever->user_data);
+
+       g_strfreev(params);
+}
+
 static int __mc_client_create(media_controller_client_s **mc_client)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -474,22 +552,34 @@ static int __mc_client_unregister_filter_listener(media_controller_client_s *mc_
        return ret;
 }
 
+static int __mc_client_check_server(void *db_handle, const char *server_name)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       bool exist_server = FALSE;
+
+       mc_retvm_if(db_handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "db_handle is NULL");
+       mc_retvm_if(!MC_STRING_VALID(server_name), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid server_name");
+
+       ret = mc_db_check_server_table_exist(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");
+
+       return ret;
+}
+
 static int __mc_client_send_command(mc_client_h client, const char *server_name, const char *command_type, const char *command, const char *signal_name, const char *message, char **request_id)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        media_controller_client_s *mc_client = (media_controller_client_s *)client;
-       bool exist_server = FALSE;
        char *interface_name = NULL;
 
        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(command_type), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid command_type");
        mc_retvm_if(!MC_STRING_VALID(signal_name), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid signal_name");
        mc_retvm_if(!MC_STRING_VALID(message), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid message");
 
-       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_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
 
        ret = mc_util_set_command_available(MC_PRIV_TYPE_CLIENT, mc_client->client_name, command_type, command);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret);
@@ -567,7 +657,7 @@ static int __mc_client_set_updated_cb(mc_client_h client, mc_client_receive_even
 
                MC_SAFE_FREE(interface_name);
 
-       } else if (event == MC_EVENT_METADATA) {
+       } else if ((event == MC_EVENT_METADATA) || event == MC_EVENT_PLAYBACK_ABILITY) {
                ret = mc_ipc_register_listener(&mc_client->listeners, mc_client->dconn, MC_DBUS_UPDATE_INTERFACE, cb_event[event].signal_name,
                                                cb_event[event].cb_func, (void *)(mc_client));
        } else {
@@ -745,6 +835,35 @@ int mc_client_unset_custom_event_received_cb(mc_client_h client)
        return __mc_client_unset_updated_cb(client, MC_EVENT_SERVER_CUSTOM);
 }
 
+int mc_client_set_playback_ability_updated_cb(mc_client_h client, mc_playback_ability_updated_cb callback, void *user_data)
+{
+       return __mc_client_set_updated_cb(client, MC_EVENT_PLAYBACK_ABILITY, callback, user_data);
+}
+int mc_client_unset_playback_ability_updated_cb(mc_client_h client)
+{
+       return __mc_client_unset_updated_cb(client, MC_EVENT_PLAYBACK_ABILITY);
+}
+
+int mc_client_set_shuffle_ability_updated_cb(mc_client_h client, mc_shuffle_ability_updated_cb callback, void *user_data)
+{
+       return __mc_client_set_updated_cb(client, MC_EVENT_SHUFFLE_ABILITY, callback, user_data);
+}
+
+int mc_client_unset_shuffle_ability_updated_cb(mc_client_h client)
+{
+       return __mc_client_unset_updated_cb(client, MC_EVENT_SHUFFLE_ABILITY);
+}
+
+int mc_client_set_repeat_ability_updated_cb(mc_client_h client, mc_repeat_ability_updated_cb callback, void *user_data)
+{
+       return __mc_client_set_updated_cb(client, MC_EVENT_REPEAT_ABILITY, callback, user_data);
+}
+
+int mc_client_unset_repeat_ability_updated_cb(mc_client_h client)
+{
+       return __mc_client_unset_updated_cb(client, MC_EVENT_REPEAT_ABILITY);
+}
+
 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;
@@ -752,7 +871,7 @@ int mc_client_subscribe(mc_client_h client, const mc_subscription_type_e subscri
 
        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(((subscription_type < MC_SUBSCRIPTION_TYPE_SERVER_STATE) || (subscription_type > MC_SUBSCRIPTION_TYPE_PLAYLIST)) , MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid subscription_type [%d]", subscription_type);
+       mc_retvm_if(((subscription_type < MC_SUBSCRIPTION_TYPE_SERVER_STATE) || (subscription_type > MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY)) , MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid subscription_type [%d]", subscription_type);
        mc_retvm_if(mc_client->updated_cb[subscription_type].callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid callback");
 
        ret = mc_ipc_unregister_listener(&mc_client->listeners, mc_client->dconn, MC_DBUS_UPDATE_INTERFACE, cb_event[subscription_type].signal_name);
@@ -775,7 +894,7 @@ int mc_client_unsubscribe(mc_client_h client, const mc_subscription_type_e subsc
 
        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(((subscription_type < MC_SUBSCRIPTION_TYPE_SERVER_STATE) || (subscription_type > MC_SUBSCRIPTION_TYPE_PLAYLIST)) , MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid subscription_type [%d]", subscription_type);
+       mc_retvm_if(((subscription_type < MC_SUBSCRIPTION_TYPE_SERVER_STATE) || (subscription_type > MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY)) , MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid subscription_type [%d]", subscription_type);
 
        mc_retvm_if(mc_client->updated_cb[subscription_type].callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid callback. No list to unsubscribe [%d]", subscription_type);
        mc_retvm_if(mc_client->updated_cb[subscription_type].filter_list == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid filter_list. No list to unsubscribe [%d]", subscription_type);
@@ -796,7 +915,7 @@ int mc_client_foreach_server_subscribed(mc_client_h client, const mc_subscriptio
 
        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(((subscription_type < MC_SUBSCRIPTION_TYPE_SERVER_STATE) || (subscription_type > MC_SUBSCRIPTION_TYPE_PLAYLIST)) , MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid subscription_type [%d]", subscription_type);
+       mc_retvm_if(((subscription_type < MC_SUBSCRIPTION_TYPE_SERVER_STATE) || (subscription_type > MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY)) , MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid subscription_type [%d]", subscription_type);
 
        filter_list = mc_client->updated_cb[subscription_type].filter_list;
 
@@ -857,6 +976,18 @@ int mc_client_get_playlist_item_index(mc_playback_h playback, char **index)
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
+int mc_client_get_playback_content_type(mc_playback_h playback, mc_content_type_e *content_type)
+{
+       media_controller_playback_s *mc_playback = (media_controller_playback_s *)playback;
+
+       mc_retvm_if(playback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       mc_retvm_if(content_type == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "content_type is NULL");
+
+       *content_type = mc_playback->content_type;
+
+       return MEDIA_CONTROLLER_ERROR_NONE;
+}
+
 int mc_client_get_metadata(mc_metadata_h metadata, mc_meta_e attribute, char **value)
 {
        char *meta_val = NULL;
@@ -1000,16 +1131,12 @@ int mc_client_get_server_playback_info(mc_client_h client, const char *server_na
 {
        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(playback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "playback Handle 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);
-       /* TODO: Change error to new type(ex. SERVER_NOT_ACTIVATED or SERVER_NOT_FOUND) */
-       mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid server_name");
+       ret = __mc_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
 
        ret = mc_db_get_playback_info(mc_client->db_handle, server_name, playback);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail mc_db_get_playback_info [%d]", ret);
@@ -1021,15 +1148,12 @@ int mc_client_get_server_metadata(mc_client_h client, const char *server_name, m
 {
        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(metadata == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "metadata Handle 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_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
 
        ret = mc_db_get_metadata_info(mc_client->db_handle, server_name, metadata);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail mc_db_get_metadata_info [%d]", ret);
@@ -1041,15 +1165,12 @@ int mc_client_get_server_shuffle_mode(mc_client_h client, const char *server_nam
 {
        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(mode == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "mode 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_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
 
        ret = mc_db_get_shuffle_mode(mc_client->db_handle, server_name, mode);
 
@@ -1060,21 +1181,34 @@ int mc_client_get_server_repeat_mode(mc_client_h client, const char *server_name
 {
        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(mode == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "mode 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_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
 
        ret = mc_db_get_repeat_mode(mc_client->db_handle, server_name, mode);
 
        return ret;
 }
 
+int mc_client_get_server_icon(mc_client_h client, const char *server_name, char **uri)
+{
+       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(uri == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "uri is NULL");
+
+       ret = __mc_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
+
+       ret = mc_db_get_icon_uri(mc_client->db_handle, server_name, uri);
+
+       return ret;
+}
+
 int mc_client_foreach_server_playlist(mc_client_h client, const char *server_name, mc_playlist_cb callback, void *user_data)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -1308,6 +1442,57 @@ int mc_client_send_event_reply(mc_client_h client, const char *server_name, cons
        return ret;
 }
 
+int mc_client_get_server_playback_ability(mc_client_h client, const char *server_name, mc_playback_ability_h *ability)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_client_s *mc_client = (media_controller_client_s *)client;
+
+       mc_retvm_if(client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "client is NULL");
+       mc_retvm_if(ability == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "ability is NULL");
+
+       ret = __mc_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
+
+       ret = mc_db_get_pb_action_ability(mc_client->db_handle, server_name, ability);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_get_pb_action_ability [%d]", ret);
+
+       return ret;
+}
+
+int mc_client_get_server_shuffle_ability_support(mc_client_h client, const char *server_name, mc_ability_support_e *support)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_client_s *mc_client = (media_controller_client_s *)client;
+
+       mc_retvm_if(client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "client is NULL");
+       mc_retvm_if(support == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "supported is NULL");
+
+       ret = __mc_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
+
+       ret = mc_db_get_ability_supported(mc_client->db_handle, server_name, MC_ABILITY_SHUFFLE, support);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_get_ability_supported [%d]", ret);
+
+       return ret;
+}
+
+int mc_client_get_server_repeat_ability_support(mc_client_h client, const char *server_name, mc_ability_support_e *support)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_client_s *mc_client = (media_controller_client_s *)client;
+
+       mc_retvm_if(client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "client is NULL");
+       mc_retvm_if(support == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "supported is NULL");
+
+       ret = __mc_client_check_server(mc_client->db_handle, server_name);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error __mc_client_check_server [%d]", ret);
+
+       ret = mc_db_get_ability_supported(mc_client->db_handle, server_name, MC_ABILITY_REPEAT, support);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_get_ability_supported [%d]", ret);
+
+       return ret;
+}
+
 int mc_client_destroy(mc_client_h client)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -1319,7 +1504,7 @@ int mc_client_destroy(mc_client_h client)
        mc_retvm_if(mc_client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
 
        /*Unregister all filter listener*/
-       for (idx = 0; idx <= MC_SUBSCRIPTION_TYPE_PLAYLIST; idx++) {
+       for (idx = 0; idx <= MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY; idx++) {
                ret = __mc_client_unregister_filter_listener(mc_client, &mc_client->updated_cb[idx].filter_list, NULL, cb_event[idx].signal_name);
                if (ret != MEDIA_CONTROLLER_ERROR_NONE)
                        mc_error("Error __mc_client_unregister_filter_listener [%d]", ret);
index 42b26705a03706dbcfc44254812e15c601e4ac12..e4652392817a5a48d69aa3f031dd76efaf372cfe 100755 (executable)
@@ -33,6 +33,7 @@ typedef enum {
        MC_SERVER_FIELD_PLAYBACK_STATE,
        MC_SERVER_FIELD_PLAYBACK_POSITION,
        MC_SERVER_FIELD_PLAYLIST_INDEX,
+       MC_SERVER_FIELD_PLAYBACK_CONTENT_TYPE,
        MC_SERVER_FIELD_TITLE,
        MC_SERVER_FIELD_ARTIST,
        MC_SERVER_FIELD_ALBUM,
@@ -109,6 +110,85 @@ static int __mc_db_get_int_value_of_key(void *handle, const char *server_name, c
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
+static int __mc_db_get_ulonglong_value_of_key(void *handle, const char *server_name, const char *key, unsigned long long *value)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       char *sql_str = NULL;
+       sqlite3_stmt *stmt = NULL;
+       sqlite3 *db_handle = (sqlite3 *)handle;
+
+       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(key == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "key is NULL");
+       mc_retvm_if(value == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "value is NULL");
+
+       sql_str = sqlite3_mprintf("SELECT %s FROM '%q';", key, server_name);
+       mc_retvm_if(!MC_STRING_VALID(sql_str), MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "SQL string is null");
+
+       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_error("end of row [%s]", sqlite3_errmsg(db_handle));
+               SQLITE3_FINALIZE(stmt);
+               SQLITE3_SAFE_FREE(sql_str);
+               return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
+       }
+       while (SQLITE_ROW == ret) {
+               *value = (unsigned long long)sqlite3_column_int64(stmt, 0);
+               ret = sqlite3_step(stmt);
+       }
+
+       SQLITE3_FINALIZE(stmt);
+       SQLITE3_SAFE_FREE(sql_str);
+
+       return MEDIA_CONTROLLER_ERROR_NONE;
+}
+
+static int __mc_db_get_text_value_of_key(void *handle, const char *server_name, const char *key, char **value)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       char *sql_str = NULL;
+       sqlite3_stmt *stmt = NULL;
+       sqlite3 *db_handle = (sqlite3 *)handle;
+
+       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(key == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "key is NULL");
+
+       sql_str = sqlite3_mprintf("SELECT %s FROM '%q';", key, server_name);
+       mc_retvm_if(!MC_STRING_VALID(sql_str), MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "SQL string is null");
+
+       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_error("end of row [%s]", sqlite3_errmsg(db_handle));
+               SQLITE3_FINALIZE(stmt);
+               SQLITE3_SAFE_FREE(sql_str);
+               return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
+       }
+       while (SQLITE_ROW == ret) {
+               *value = g_strdup((const char *)sqlite3_column_text(stmt, 0));
+               ret = sqlite3_step(stmt);
+       }
+
+       SQLITE3_FINALIZE(stmt);
+       SQLITE3_SAFE_FREE(sql_str);
+
+       return MEDIA_CONTROLLER_ERROR_NONE;
+}
+
 static char* __mc_get_db_name(uid_t uid)
 {
        char result_psswd[MC_FILE_PATH_LEN_MAX] = {0, };
@@ -198,7 +278,7 @@ int mc_db_connect(void **handle)
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
-int mc_db_update_playback_info(void *handle, const char *server_name, int playback_state, unsigned long long playback_position, const char *index)
+int mc_db_update_playback_info(void *handle, const char *server_name, const media_controller_playback_s playback)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        char *sql_str = NULL;
@@ -206,11 +286,12 @@ int mc_db_update_playback_info(void *handle, const char *server_name, int playba
        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 = g_strdup_printf("%s%s%s%s%d%s%llu%s%s", MC_DB_CMD_UPDATE_PLAYBACK, MC_STRING_DELIMITER,
+       sql_str = g_strdup_printf("%s%s%s%s%d%s%llu%s%s%s%d", MC_DB_CMD_UPDATE_PLAYBACK, MC_STRING_DELIMITER,
                        server_name,  MC_STRING_DELIMITER,
-                       playback_state,  MC_STRING_DELIMITER,
-                       playback_position,  MC_STRING_DELIMITER,
-                       index);
+                       playback.state,  MC_STRING_DELIMITER,
+                       playback.position,  MC_STRING_DELIMITER,
+                       playback.index,  MC_STRING_DELIMITER,
+                       playback.content_type);
        mc_retvm_if(sql_str == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "fail making sql_str");
 
        ret = __mc_db_update_db(handle, MC_PRIV_TYPE_SERVER, sql_str);
@@ -285,6 +366,41 @@ int mc_db_update_repeat_mode(void *handle, const char *server_name, int repeat_m
        return ret;
 }
 
+int mc_db_update_icon_uri(void *handle, const char *server_name, const char *uri)
+{
+       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");
+       mc_retvm_if(uri == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "uri is NULL");
+
+       sql_str = g_strdup_printf("%s%s%s%s%s", MC_DB_CMD_UPDATE_ICON, MC_STRING_DELIMITER, server_name,  MC_STRING_DELIMITER, uri);
+
+       ret = __mc_db_update_db(handle, MC_PRIV_TYPE_SERVER, sql_str);
+
+       MC_SAFE_FREE(sql_str);
+
+       return ret;
+}
+
+int mc_db_update_ability_supported(void *handle, const char *server_name, const media_controller_ability_s ability_supported)
+{
+       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 = g_strdup_printf("%s%s%s%s%llu%s%llu", MC_DB_CMD_UPDATE_ABILITY, MC_STRING_DELIMITER, server_name, MC_STRING_DELIMITER, (unsigned long long)ability_supported.decided, MC_STRING_DELIMITER, (unsigned long long)ability_supported.supported);
+
+       ret = __mc_db_update_db(handle, MC_PRIV_TYPE_SERVER, sql_str);
+
+       MC_SAFE_FREE(sql_str);
+
+       return ret;
+}
+
 int mc_db_get_latest_server_name(void *handle, char **latest_server_name)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -335,6 +451,7 @@ int mc_db_get_playback_info(void *handle, const char *server_name, mc_playback_h
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        mc_playback_states_e playback_state = MC_PLAYBACK_STATE_PLAYING;
        unsigned long long position = 0;
+       mc_content_type_e content_type = MC_CONTENT_TYPE_UNDECIDED;
        media_controller_playback_s *_playback = NULL;
        char *sql_str = NULL;
        sqlite3_stmt *stmt = NULL;
@@ -345,7 +462,7 @@ int mc_db_get_playback_info(void *handle, const char *server_name, mc_playback_h
        mc_retvm_if(server_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "server_name is NULL");
        mc_retvm_if(playback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "playback is NULL");
 
-       sql_str = sqlite3_mprintf("SELECT playback_state, playback_position, playlist_index FROM '%q';", server_name);
+       sql_str = sqlite3_mprintf("SELECT playback_state, playback_position, playlist_index, playback_content_type FROM '%q';", server_name);
        mc_retvm_if(!MC_STRING_VALID(sql_str), MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "SQL string is null");
 
        ret = sqlite3_prepare_v2(db_handle, sql_str, strlen(sql_str), &stmt, NULL);
@@ -366,6 +483,7 @@ int mc_db_get_playback_info(void *handle, const char *server_name, mc_playback_h
        playback_state = sqlite3_column_int(stmt, 0);
        position = (unsigned long long)sqlite3_column_int64(stmt, 1);
        index = g_strdup((const char *)sqlite3_column_text(stmt, 2));
+       content_type = sqlite3_column_int(stmt, 3);
 
        SQLITE3_FINALIZE(stmt);
        SQLITE3_SAFE_FREE(sql_str);
@@ -380,6 +498,7 @@ int mc_db_get_playback_info(void *handle, const char *server_name, mc_playback_h
        _playback->state = playback_state;
        _playback->position = position;
        _playback->index = index;
+       _playback->content_type = content_type;
 
        *playback = (mc_playback_h)_playback;
 
@@ -396,6 +515,7 @@ int mc_db_get_metadata_info(void *handle, const char *server_name, mc_metadata_h
 
        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(metadata == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "metadata is NULL");
 
        sql_str = sqlite3_mprintf("SELECT * FROM '%q';", server_name);
        mc_retvm_if(!MC_STRING_VALID(sql_str), MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "SQL string is null");
@@ -489,6 +609,79 @@ int mc_db_get_repeat_mode(void *handle, const char *server_name, mc_repeat_mode_
        return ret;
 }
 
+int mc_db_get_icon_uri(void *handle, const char *server_name, char **uri)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+
+       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");
+
+       ret = __mc_db_get_text_value_of_key(handle, server_name, "icon_uri", uri);
+
+       return ret;
+}
+
+int mc_db_get_ability_supported(void *handle, const char *server_name, mc_ability_e ability, mc_ability_support_e *supported)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_ability_s basic_ability = {0, 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((ability < MC_ABILITY_ACTION || ability > MC_ABILITY_REPEAT), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "ability is Invalid");
+
+       ret = __mc_db_get_ulonglong_value_of_key(handle, server_name, "ability_decided", &basic_ability.decided);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "__mc_db_get_text_value_of_key failed");
+
+       ret = __mc_db_get_ulonglong_value_of_key(handle, server_name, "ability_supported", &basic_ability.supported);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "__mc_db_get_text_value_of_key failed");
+
+       mc_secure_debug("IsDecided: %d", MC_BIT64_IS_TRUE(basic_ability.decided, ability));
+       mc_secure_debug("IsSupported: %d", MC_BIT64_IS_TRUE(basic_ability.supported, ability));
+
+       if (MC_BIT64_IS_TRUE(basic_ability.decided, ability)) {
+               if (MC_BIT64_IS_TRUE(basic_ability.supported, ability))
+                       *supported = MC_ABILITY_SUPPORTED_YES;
+               else
+                       *supported = MC_ABILITY_SUPPORTED_NO;
+       } else {
+               *supported = MC_ABILITY_SUPPORTED_UNDECIDED;
+       }
+
+       mc_secure_debug("ability: %d supported: %d", ability, *supported);
+
+       return ret;
+}
+
+int mc_db_get_pb_action_ability(void *handle, const char *server_name, mc_playback_ability_h *ability)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_ability_s *basic_ability = 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");
+       mc_retvm_if(ability == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "ability is NULL");
+
+       basic_ability = (media_controller_ability_s *)calloc(1, sizeof(media_controller_ability_s));
+       mc_retvm_if(basic_ability == NULL, MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY, "malloc failed");
+
+       ret = __mc_db_get_ulonglong_value_of_key(handle, server_name, "ability_decided", &basic_ability->decided);
+       if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+               MC_SAFE_FREE(basic_ability);
+               return ret;
+       }
+
+       ret = __mc_db_get_ulonglong_value_of_key(handle, server_name, "ability_supported", &basic_ability->supported);
+       if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+               MC_SAFE_FREE(basic_ability);
+               return ret;
+       }
+
+       *ability = (mc_playback_ability_h)basic_ability;
+
+       return ret;
+}
+
 int mc_db_get_foreach_playlist(void *handle, const char *server_name, mc_playlist_cb callback, void *user_data)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -580,17 +773,17 @@ int mc_db_get_playlist_item(void *handle, const char *server_name, char *playlis
                }
 
                index = g_strdup((char *)sqlite3_column_text(stmt, 2)); //0 : server_name, 1 : playlist_name
-               _metadata->title = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_TITLE -2));
-               _metadata->artist = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_ARTIST -2));
-               _metadata->album = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_ALBUM -2));
-               _metadata->author = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_AUTHOR -2));
-               _metadata->genre = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_GENRE -2));
-               _metadata->duration = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_DURATION -2));
-               _metadata->date = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_DATE -2));
-               _metadata->copyright = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_COPYRIGHT -2));
-               _metadata->description = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_DESCRIPTION -2));
-               _metadata->track_num = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_TRACK_NUM -2));
-               _metadata->picture = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_PICTURE -2));
+               _metadata->title = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_TITLE -3));
+               _metadata->artist = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_ARTIST -3));
+               _metadata->album = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_ALBUM -3));
+               _metadata->author = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_AUTHOR -3));
+               _metadata->genre = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_GENRE -3));
+               _metadata->duration = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_DURATION -3));
+               _metadata->date = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_DATE -3));
+               _metadata->copyright = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_COPYRIGHT -3));
+               _metadata->description = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_DESCRIPTION -3));
+               _metadata->track_num = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_TRACK_NUM -3));
+               _metadata->picture = g_strdup((const char *)sqlite3_column_text(stmt, MC_SERVER_FIELD_PICTURE -3));
 
                if (callback(index, (mc_metadata_h)_metadata, user_data) == false) {
                        MC_SAFE_FREE(index);
index fb01b7d492138701ced53e95810d32583a30d602..7f5dbb63dca394a7d73dcc3afbcb63932284d50b 100755 (executable)
@@ -135,3 +135,57 @@ int mc_metadata_get(mc_metadata_h metadata, mc_meta_e attribute, char **value)
 
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
+
+int mc_playback_ability_clone(mc_playback_ability_h src, mc_playback_ability_h *dst)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_ability_s *_src = (media_controller_ability_s *)src;
+
+       mc_retvm_if(_src == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "invalid src");
+       mc_retvm_if(dst == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "invalid dst");
+
+       media_controller_ability_s *_dst = (media_controller_ability_s*)calloc(1, sizeof(media_controller_ability_s));
+       mc_retvm_if(_dst == NULL, MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
+
+       _dst->decided = _src->decided;
+       _dst->supported = _src->supported;
+
+       *dst = (mc_playback_ability_h)_dst;
+
+       return ret;
+}
+
+int mc_playback_ability_destroy(mc_playback_ability_h ability)
+{
+       media_controller_ability_s *mc_ability = (media_controller_ability_s *)ability;
+
+       mc_retvm_if(mc_ability == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+
+       MC_SAFE_FREE(mc_ability);
+
+       return MEDIA_CONTROLLER_ERROR_NONE;
+}
+
+int mc_playback_action_is_supported(mc_playback_ability_h ability, mc_playback_action_e action, mc_ability_support_e *supported)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_ability_s *mc_ability = (media_controller_ability_s *)ability;
+
+       mc_retvm_if(mc_ability == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "ability is NULL");
+       mc_retvm_if(((action < MC_PLAYBACK_ACTION_PLAY) || (action > MC_PLAYBACK_ACTION_TOGGLE_PLAY_PAUSE)), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "action is invalid");
+       mc_retvm_if(supported == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "supported is NULL");
+
+       mc_secure_debug("IsDecided: %d", MC_BIT64_IS_TRUE(mc_ability->decided, (MC_ABILITY_ACTION + action)));
+       mc_secure_debug("IsSupported: %d", MC_BIT64_IS_TRUE(mc_ability->supported, (MC_ABILITY_ACTION + action)));
+
+       if (MC_BIT64_IS_TRUE(mc_ability->decided, (MC_ABILITY_ACTION + action))) {
+               if (MC_BIT64_IS_TRUE(mc_ability->supported, (MC_ABILITY_ACTION + action)))
+                       *supported = MC_ABILITY_SUPPORTED_YES;
+               else
+                       *supported = MC_ABILITY_SUPPORTED_NO;
+       } else {
+               *supported = MC_ABILITY_SUPPORTED_UNDECIDED;
+       }
+
+       return ret;
+}
index 6e4380fe86f2da89c738f16de019c2fd1843a2fe..4b6b5710d881941f658a844074c86aae9c75d7d8 100755 (executable)
@@ -36,6 +36,11 @@ static int __mc_server_create(media_controller_server_s **mc_server)
                goto ERROR;
        }
 
+       _server->playback.state = MC_PLAYBACK_STATE_NONE;
+       _server->playback.position = 0;
+       _server->playback.index = NULL;
+       _server->playback.content_type = MC_CONTENT_TYPE_UNDECIDED;
+
        _server->metadata = (media_controller_metadata_s *)calloc(1, sizeof(media_controller_metadata_s));
        if (_server->metadata == NULL) {
                mc_error("Error allocation memory");
@@ -43,6 +48,9 @@ static int __mc_server_create(media_controller_server_s **mc_server)
                goto ERROR;
        }
 
+       _server->basic_ability.decided = (unsigned long)MC_BIT64_UNSET;
+       _server->basic_ability.supported = (unsigned long)MC_BIT64_UNSET;
+
        ret = mc_ipc_get_dbus_connection(&(_server->dconn), &(_server->dref_count));
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("Error allocation memory");
@@ -459,7 +467,7 @@ static int __mc_server_current_is_latest(media_controller_server_s *mc_server, b
        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, const char* param3)
+static int __mc_server_send_message(media_controller_server_s *mc_server, const char *interface_name, const char *signal_name, const int param1, const unsigned long long param2, const char* param3, const int param4)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        char *message = NULL;
@@ -469,9 +477,11 @@ static int __mc_server_send_message(media_controller_server_s *mc_server, const
        mc_retvm_if(signal_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "signal_name is NULL");
 
        if (!g_strcmp0(MC_DBUS_SIGNAL_NAME_PLAY_BACK, signal_name))
-               message = g_strdup_printf("%s%s%d%s%llu%s%s", mc_server->server_name, MC_STRING_DELIMITER, param1, MC_STRING_DELIMITER, param2, MC_STRING_DELIMITER, param3);
+               message = g_strdup_printf("%s%s%d%s%llu%s%s%s%d", mc_server->server_name, MC_STRING_DELIMITER, param1, MC_STRING_DELIMITER, param2, MC_STRING_DELIMITER, param3, MC_STRING_DELIMITER, param4);
        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_PLAYBACK_ABILITY, 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
@@ -579,6 +589,21 @@ int mc_server_set_playlist_item_index(mc_server_h server, const char *index)
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
+int mc_server_set_playback_content_type(mc_server_h server, mc_content_type_e content_type)
+{
+       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(((content_type < MC_CONTENT_TYPE_IMAGE) || (content_type > MC_CONTENT_TYPE_OTHER)), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "content_type is invalid [%d]", content_type);
+
+       mc_debug("content type [%d]", content_type);
+
+       mc_server->playback.content_type = content_type;
+
+       return ret;
+}
+
 int mc_server_update_playback_info(mc_server_h server)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -586,15 +611,15 @@ int mc_server_update_playback_info(mc_server_h server)
 
        mc_retvm_if(mc_server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL");
 
-       mc_debug("playback info update: state [%d], position [%llu]", mc_server->playback.state, mc_server->playback.position);
+       mc_debug("playback info update: state [%d], position [%llu], index [%s], content_type [%d]", mc_server->playback.state, mc_server->playback.position, mc_server->playback.index, mc_server->playback.content_type);
 
-       ret = mc_db_update_playback_info(mc_server->db_handle, mc_server->server_name, (int)mc_server->playback.state, mc_server->playback.position, mc_server->playback.index);
+       ret = mc_db_update_playback_info(mc_server->db_handle, mc_server->server_name, mc_server->playback);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("fail mc_db_update_playback_info [%d]", ret);
                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, mc_server->playback.index);
+       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, mc_server->playback.index, mc_server->playback.content_type);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE)
                mc_error("Error __mc_server_send_message [%d]", ret);
 
@@ -626,7 +651,7 @@ int mc_server_update_shuffle_mode(mc_server_h server, mc_shuffle_mode_e mode)
        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, NULL);
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYBACK_SHUFFLE, mode, 0, NULL, 0);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
 
        return ret;
@@ -645,7 +670,7 @@ int mc_server_update_repeat_mode(mc_server_h server, mc_repeat_mode_e mode)
        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, NULL);
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYBACK_REPEAT, mode, 0, NULL, 0);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
 
        return ret;
@@ -736,7 +761,7 @@ int mc_server_update_metadata(mc_server_h server)
                                                                        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, NULL);
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_METADATA, 0, 0, NULL, 0);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
 
        return ret;
@@ -962,7 +987,7 @@ int mc_server_update_playlist_done(mc_server_h server, mc_playlist_h playlist)
                goto RELEASE;
        }
 
-       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST, MC_PLAYLIST_UPDATED, 0, _playlist->playlist_name);
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST, MC_PLAYLIST_UPDATED, 0, _playlist->playlist_name, 0);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
                mc_error("fail to __mc_server_send_message");
                goto RELEASE;
@@ -1003,7 +1028,7 @@ int mc_server_delete_playlist(mc_server_h server, mc_playlist_h playlist)
        ret = mc_db_remove_playlist(mc_server->db_handle, mc_server->server_name, _playlist->playlist_name);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to mc_db_remove_playlist");
 
-       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST, MC_PLAYLIST_REMOVED, 0, _playlist->playlist_name);
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYLIST, MC_PLAYLIST_REMOVED, 0, _playlist->playlist_name, 0);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
 
        return ret;
@@ -1457,6 +1482,88 @@ int mc_server_unset_event_reply_received_cb(mc_server_h server)
        return ret;
 }
 
+int mc_server_set_icon(mc_server_h server, const char *uri)
+{
+       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_debug("uri %s", uri);
+
+       ret = mc_db_update_icon_uri(mc_server->db_handle, mc_server->server_name, uri);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to mc_db_update_icon_uri");
+
+       return ret;
+}
+
+static int __mc_server_update_ability(mc_server_h server, int support_item, mc_ability_support_e support)
+{
+       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(((support != MC_ABILITY_SUPPORTED_YES) && (support != MC_ABILITY_SUPPORTED_NO)), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "support is invalid [%d]", support);
+
+       /* Change decided bit to 1(set) */
+       MC_BIT64_SET_BIT(mc_server->basic_ability.decided, support_item);
+
+       /* if support is supported_yes, change supported bit to 1(set), otherwise change supported bit to 0(unset) */
+       if (support == MC_ABILITY_SUPPORTED_YES)
+               MC_BIT64_SET_BIT(mc_server->basic_ability.supported, support_item);
+       else
+               MC_BIT64_UNSET_BIT(mc_server->basic_ability.supported, support_item);
+
+       return mc_db_update_ability_supported(mc_server->db_handle, mc_server->server_name, mc_server->basic_ability);
+}
+
+int mc_server_set_playback_ability(mc_server_h server, mc_playback_action_e action, mc_ability_support_e support)
+{
+       mc_retvm_if(((action < MC_PLAYBACK_ACTION_PLAY) || (action > MC_PLAYBACK_ACTION_TOGGLE_PLAY_PAUSE)), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "action is invalid [%d]", action);
+
+       return __mc_server_update_ability(server, MC_ABILITY_ACTION + action, support);
+}
+
+int mc_server_update_playback_ability(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");
+
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_PLAYBACK_ABILITY, 0, 0, NULL, 0);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
+
+       return ret;
+}
+
+int mc_server_set_shuffle_ability(mc_server_h server, mc_ability_support_e support)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_server_s *mc_server = (media_controller_server_s *)server;
+
+       ret = __mc_server_update_ability(server, MC_ABILITY_SHUFFLE, support);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_update_ability");
+
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SHUFFLE_ABILITY, support, 0, NULL, 0);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
+
+       return ret;
+}
+
+int mc_server_set_repeat_ability(mc_server_h server, mc_ability_support_e support)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_server_s *mc_server = (media_controller_server_s *)server;
+
+       ret = __mc_server_update_ability(server, MC_ABILITY_REPEAT, support);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_update_ability");
+
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_REPEAT_ABILITY, support, 0, NULL, 0);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "fail to __mc_server_send_message");
+
+       return ret;
+}
+
 int mc_server_create(mc_server_h *server)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -1538,7 +1645,7 @@ int mc_server_create(mc_server_h *server)
                return ret;
        }
 
-       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SERVER_STATE, MC_SERVER_STATE_ACTIVATE, 0, NULL);
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SERVER_STATE, MC_SERVER_STATE_ACTIVATE, 0, NULL, 0);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE)
                mc_error("Error __mc_server_send_message [%d]", ret);
 
@@ -1578,7 +1685,7 @@ int mc_server_destroy(mc_server_h server)
                        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, NULL);
+       ret = __mc_server_send_message(mc_server, MC_DBUS_UPDATE_INTERFACE, MC_DBUS_SIGNAL_NAME_SERVER_STATE, MC_SERVER_STATE_DEACTIVATE, 0, NULL, 0);
        if (ret != MEDIA_CONTROLLER_ERROR_NONE)
                mc_error("Error __mc_server_send_message [%d]", ret);
 
old mode 100755 (executable)
new mode 100644 (file)
index ddcaf50..96cd1ab
@@ -468,7 +468,7 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size)
        gchar **params = NULL;
        int i_value = 0;
        int i_value_1 = 0;
-       unsigned long long llu_value = 0;
+       unsigned long long llu_value = 0, llu_value2 = 0;
        void* _db_handle = NULL;
        bool is_playlist = FALSE;
 
@@ -491,6 +491,7 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size)
                                playback_state          INTEGER DEFAULT 0, \
                                playback_position       INTEGER DEFAULT 0, \
                                playlist_index          TEXT, \
+                               playback_content_type   INTEGER DEFAULT 4, \
                                title                           TEXT, \
                                artist                          TEXT, \
                                album                           TEXT, \
@@ -503,7 +504,10 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size)
                                track_num                       TEXT, \
                                picture                         TEXT, \
                                shuffle_mode            INTEGER DEFAULT 1, \
-                               repeat_mode                     INTEGER DEFAULT 1 \
+                               repeat_mode                     INTEGER DEFAULT 1, \
+                               icon_uri                        TEXT, \
+                               ability_decided         INTEGER DEFAULT 0, \
+                               ability_supported       INTEGER DEFAULT 0 \
                                );INSERT INTO '%q' (server_name) VALUES ('%q');",
                                params[1], params[1], params[1]);
 
@@ -526,7 +530,7 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size)
                sql_str = sqlite3_mprintf("UPDATE '%q' SET server_state=%d, playback_state=%d;", params[1], i_value, i_value_1);
 
        } else if (strncmp(MC_DB_CMD_UPDATE_PLAYBACK, params[0], strlen(MC_DB_CMD_UPDATE_PLAYBACK)) == 0) {
-               if (params[2] == NULL || params[3] == NULL || params[4] == NULL) {
+               if (params[2] == NULL || params[3] == NULL || params[4] == NULL || params[5] == NULL) {
                        mc_error("wrong query");
                        ret = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
                        goto ERROR;
@@ -534,7 +538,8 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size)
 
                mc_safe_strtoi(params[2], &i_value);
                mc_safe_strtoull(params[3], &llu_value);
-               sql_str = sqlite3_mprintf("UPDATE '%q' SET playback_state=%d, playback_position=%llu, playlist_index=%Q;", params[1], i_value, llu_value, params[4]);
+               mc_safe_strtoi(params[5], &i_value_1);
+               sql_str = sqlite3_mprintf("UPDATE '%q' SET playback_state=%d, playback_position=%llu, playlist_index=%Q, playback_content_type=%d;", params[1], i_value, llu_value, params[4], i_value_1);
 
        } else if (strncmp(MC_DB_CMD_UPDATE_META, params[0], strlen(MC_DB_CMD_UPDATE_META)) == 0) {
                sql_str = sqlite3_mprintf("UPDATE '%q' SET title=%Q, artist=%Q, album=%Q, author=%Q, genre=%Q, duration=%Q, date=%Q, copyright=%Q, description=%Q, track_num=%Q, picture=%Q",
@@ -572,6 +577,27 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size)
                sql_str = params[3];
                is_playlist = TRUE;
 
+       } else if (strncmp(MC_DB_CMD_UPDATE_ICON, params[0], strlen(MC_DB_CMD_UPDATE_ICON)) == 0) {
+               if (params[2] == NULL) {
+                       mc_error("wrong query");
+                       ret = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
+                       goto ERROR;
+               }
+
+               sql_str = sqlite3_mprintf("UPDATE '%q' SET icon_uri=%Q;", params[1], params[2]);
+
+       } else if (strncmp(MC_DB_CMD_UPDATE_ABILITY, params[0], strlen(MC_DB_CMD_UPDATE_ABILITY)) == 0) {
+               if (params[2] == NULL || params[3] == NULL) {
+                       mc_error("wrong query");
+                       ret = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;
+                       goto ERROR;
+               }
+
+               mc_safe_strtoull(params[2], &llu_value);
+               mc_safe_strtoull(params[3], &llu_value2);
+
+               sql_str = sqlite3_mprintf("UPDATE '%q' SET ability_decided=%llu, ability_supported=%llu;", params[1], llu_value, llu_value2);
+
        } else if (strncmp(MC_DB_CMD_REMOVE_SERVER_LIST, params[0], strlen(MC_DB_CMD_REMOVE_SERVER_LIST)) == 0) {
                sql_str = sqlite3_mprintf("DELETE FROM %q WHERE server_name = '%q';", MC_DB_TABLE_SERVER_LIST, params[1]);
 
index fac56ee42fda66b576ffbd3cfc4963afa24ce1ae..f8863495351463e09a192dfa8cbd7afd858a9cfb 100755 (executable)
@@ -98,12 +98,14 @@ void _mc_playback_updated_cb(const char *server_name, mc_playback_h playback, vo
        unsigned long long position = 0;
        mc_playback_states_e playback_state = MC_PLAYBACK_STATE_NONE;
        char *index = NULL;
+       mc_content_type_e content_type = MC_CONTENT_TYPE_UNDECIDED;
 
        mc_client_get_playback_position(playback, &position);
        mc_client_get_playback_state(playback, &playback_state);
        mc_client_get_playlist_item_index(playback, &index);
+       mc_client_get_playback_content_type(playback, &content_type);
 
-       mc_debug("[Client:%s] Playback updated from server[%s] playback_state[%d] position[%lld] index[%s]", _client->client_name, server_name, playback_state, position, index);
+       mc_debug("[Client:%s] Playback updated from server[%s] playback_state[%d] position[%lld] index[%s] content_type[%d]", _client->client_name, server_name, playback_state, position, index, content_type);
 
        MC_SAFE_FREE(index);
 }
@@ -162,6 +164,15 @@ bool _mc_activated_server_cb(const char *server_name, void *user_data)
 {
        media_controller_client_s *_client = (media_controller_client_s *)g_mc_client;
        mc_debug("[Client:%s] Activated server_name: %s", _client->client_name, server_name);
+
+       mc_ability_support_e supported = MC_ABILITY_SUPPORTED_UNDECIDED;
+
+       mc_client_get_server_shuffle_ability_support(g_mc_client, server_name, &supported);
+       g_print("== shuffle ability %d \n", supported);
+
+       mc_client_get_server_repeat_ability_support(g_mc_client, server_name, &supported);
+       g_print("== repeat ability %d \n", supported);
+
        return TRUE;
 }
 
@@ -227,6 +238,36 @@ void _mc_custom_event_received_cb(const char *server_name, const char *request_i
        bundle_free(bundle_reply);
 }
 
+void _mc_playback_ability_updated_cb(const char *server_name, mc_playback_ability_h ability, void *user_data)
+{
+       int ret = MEDIA_CONTROLLER_ERROR_NONE;
+       media_controller_client_s *_client = (media_controller_client_s *)g_mc_client;
+       int idx = 0;
+       mc_ability_support_e supported = MC_ABILITY_SUPPORTED_UNDECIDED;
+
+       mc_debug("[Client:%s] playback_ability updated from server[%s]", _client->client_name, server_name);
+
+       for (idx = 0; idx <= MC_PLAYBACK_ACTION_TOGGLE_PLAY_PAUSE; idx++) {
+               ret = mc_playback_action_is_supported(ability, idx, &supported);
+               if (ret != MEDIA_CONTROLLER_ERROR_NONE)
+                       mc_error("Fail to mc_playback_action_is_supported. action : [%d] ret : [%d]", idx, ret);
+
+               g_print("action support item [%d], supported [%d] \n", idx, supported);
+       }
+}
+
+void _mc_shuffle_ability_updated_cb(const char *server_name, mc_ability_support_e support, void *user_data)
+{
+       media_controller_client_s *_client = (media_controller_client_s *)g_mc_client;
+       mc_debug("[Client:%s] shuffle_ability(%d) updated from server[%s]", _client->client_name, support, server_name);
+}
+
+void _mc_repeat_ability_updated_cb(const char *server_name, mc_ability_support_e support, void *user_data)
+{
+       media_controller_client_s *_client = (media_controller_client_s *)g_mc_client;
+       mc_debug("[Client:%s] repeat_ability(%d) updated from server[%s]", _client->client_name, support, server_name);
+}
+
 static gboolean _create()
 {
        g_print("== create \n");
@@ -287,6 +328,15 @@ static gboolean _set_callback()
        ret = mc_client_set_custom_event_received_cb(g_mc_client, _mc_custom_event_received_cb, NULL);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_custom_event_received_cb [%d]", ret);
 
+       ret = mc_client_set_playback_ability_updated_cb(g_mc_client, _mc_playback_ability_updated_cb, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_playback_ability_updated_cb [%d]", ret);
+
+       ret = mc_client_set_shuffle_ability_updated_cb(g_mc_client, _mc_shuffle_ability_updated_cb, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_shuffle_ability_updated_cb [%d]", ret);
+
+       ret = mc_client_set_repeat_ability_updated_cb(g_mc_client, _mc_repeat_ability_updated_cb, NULL);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_repeat_ability_updated_cb [%d]", ret);
+
        mc_debug_fleave();
 
        return ret;
@@ -322,6 +372,15 @@ static gboolean _unset_callback()
        ret = mc_client_unset_custom_event_received_cb(g_mc_client);
        mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_custom_event_received_cb [%d]", ret);
 
+       ret = mc_client_unset_playback_ability_updated_cb(g_mc_client);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_playback_ability_updated_cb [%d]", ret);
+
+       ret = mc_client_unset_shuffle_ability_updated_cb(g_mc_client);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_shuffle_ability_updated_cb [%d]", ret);
+
+       ret = mc_client_unset_repeat_ability_updated_cb(g_mc_client);
+       mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_repeat_ability_updated_cb [%d]", ret);
+
        mc_debug_fleave();
 
        return TRUE;
@@ -380,6 +439,11 @@ static gboolean _get_info(int type)
        mc_shuffle_mode_e shuffle_mode;
        mc_repeat_mode_e repeate_mode;
        char *index = NULL;
+       mc_content_type_e content_type = MC_CONTENT_TYPE_UNDECIDED;
+       char *icon_url = NULL;
+       mc_playback_ability_h ability = NULL;
+       mc_ability_support_e support = MC_ABILITY_SUPPORTED_UNDECIDED;
+       unsigned int idx = 0;
 
        mc_debug_fenter();
 
@@ -407,7 +471,11 @@ static gboolean _get_info(int type)
                if (ret != MEDIA_CONTROLLER_ERROR_NONE)
                        g_print("Fail to get playback position");
 
-               g_print("playback state [%d], position [%lld], index [%s]", playback_state, playback_position, index);
+               ret = mc_client_get_playback_content_type(playback, &content_type);
+               if (ret != MEDIA_CONTROLLER_ERROR_NONE)
+                       g_print("Fail to get playback content type");
+
+               g_print("playback state [%d], position [%lld], index [%s], content_type[%d]", playback_state, playback_position, index, content_type);
 
                MC_SAFE_FREE(index);
 
@@ -447,6 +515,40 @@ static gboolean _get_info(int type)
                ret = mc_client_foreach_server_playlist(g_mc_client, g_server_name, server_playlist_list_cb, NULL);
                mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_playlist [%d]", ret);
 
+               break;
+       case 7:
+               ret = mc_client_get_server_icon(g_mc_client, g_server_name, &icon_url);
+               mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_icon [%d]", ret);
+
+               g_print("icon url: %s", icon_url);
+
+               MC_SAFE_FREE(index);
+               break;
+       case 8:
+               ret = mc_client_get_server_playback_ability(g_mc_client, g_server_name, &ability);
+               mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_playback_ability [%d]", ret);
+
+               for (idx = 0; idx <= MC_PLAYBACK_ACTION_TOGGLE_PLAY_PAUSE; idx++) {
+                       ret = mc_playback_action_is_supported(ability, idx, &support);
+                       if (ret != MEDIA_CONTROLLER_ERROR_NONE)
+                               mc_error("Fail to mc_playback_action_is_supported. action : [%d] ret : [%d]", idx, ret);
+
+                       g_print("action support item [%d], supported [%d] \n", idx, support);
+               }
+
+               ret = mc_playback_ability_destroy(ability);
+               mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_playback_ability_destroy [%d]", ret);
+
+               ret = mc_client_get_server_shuffle_ability_support(g_mc_client, g_server_name, &support);
+               mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_shuffle_ability_support [%d]", ret);
+
+               g_print("shuffle_ability: %d \n", support);
+
+               ret = mc_client_get_server_repeat_ability_support(g_mc_client, g_server_name, &support);
+               mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_get_server_repeat_ability_support [%d]", ret);
+
+               g_print("repeat_ability: %d \n", support);
+
                break;
        default:
                g_print("== unknown type!\n");
@@ -565,7 +667,7 @@ static gboolean _subscribe()
 
        mc_debug_fenter();
 
-       for (idx = 0; idx <= MC_SUBSCRIPTION_TYPE_PLAYLIST; idx++) {
+       for (idx = 0; idx <= MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY; idx++) {
                ret = mc_client_subscribe(g_mc_client, idx, g_server_name);
                if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
                        g_print("Fail to mc_client_subscribe");
@@ -585,7 +687,7 @@ static gboolean _unsubscribe()
 
        mc_debug_fenter();
 
-       for (idx = 0; idx <= MC_SUBSCRIPTION_TYPE_PLAYLIST; idx++) {
+       for (idx = 0; idx <= MC_SUBSCRIPTION_TYPE_REPEAT_ABILITY; idx++) {
                ret = mc_client_unsubscribe(g_mc_client, idx, g_server_name);
                if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
                        g_print("Fail to mc_client_unsubscribe");
@@ -695,7 +797,9 @@ static void display_information_menu(void)
        g_print("3. get latest server metadata \n");
        g_print("4. get latest server shuffle mode \n");
        g_print("5. get latest server repeate mode \n");
-       g_print("6. get playlist \n");
+       g_print("6. get latest server playlist \n");
+       g_print("7. get latest servericon URL \n");
+       g_print("8. get latest server ability \n");
        g_print("0. back \n");
        g_print("----------------------------------------------------\n");
        g_print("====================================================\n");
@@ -750,6 +854,10 @@ void _interpret_information_menu(char *cmd)
                        _get_info(5);
                else if (!strncmp(cmd, "6", len))
                        _get_info(6);
+               else if (!strncmp(cmd, "7", len))
+                       _get_info(7);
+               else if (!strncmp(cmd, "8", len))
+                       _get_info(8);
                else if (!strncmp(cmd, "0", len))
                        reset_current_menu_state();
                else
index bcbb55d259ffa111188dd1ed7b668e386df9b685..49db3389a6d3f3d7c27fe4fe48fdb5e1dfc1e02a 100755 (executable)
@@ -39,6 +39,8 @@ 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;
+static mc_ability_support_e g_ability_support;
+
 
 /* for sending event */
 static char *g_event_name = NULL;
@@ -66,6 +68,7 @@ enum {
        CURRENT_STATE_SET_PLAYBACK_STATE,
        CURRENT_STATE_SET_PLAYBACK_POSITION,
        CURRENT_STATE_SET_ITEM_ID,
+       CURRENT_STATE_SET_CONTENT_TYPE,
        CURRENT_STATE_SET_METADATA_NAME,
        CURRENT_STATE_SET_METADATA_VALUE,
 };
@@ -479,7 +482,8 @@ static gboolean _set_info(int type, char *cmd)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        int playback_state = 0;
-       unsigned long long playback_position;
+       int content_type = 0;
+       unsigned long long playback_position = 0;
        char *metadata = NULL;
 
        g_print("== get information [%d]\n", type);
@@ -514,6 +518,16 @@ static gboolean _set_info(int type, char *cmd)
                g_print("set media id: %s", cmd);
                break;
 
+       case CURRENT_STATE_SET_CONTENT_TYPE:
+               content_type = atoi(cmd);
+               ret = mc_server_set_playback_content_type(g_mc_server, content_type);
+               if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+                       g_print("Fail to set content type");
+                       return FALSE;
+               }
+               g_print("set content type : %d", content_type);
+               break;
+
        case CURRENT_STATE_SET_METADATA_NAME:
                g_metadata_type = atoi(cmd);
                g_print("set metadata name: %d", g_metadata_type);
@@ -596,6 +610,52 @@ static gboolean _update_info(int type)
                        return FALSE;
                }
                break;
+       case 6:
+               ret = mc_server_set_icon(g_mc_server, "test_uri");
+               if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+                       g_print("Fail to mc_server_set_icon. err=%d", ret);
+                       return FALSE;
+               }
+               break;
+       case 7:
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_PLAY, MC_ABILITY_SUPPORTED_YES);
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_PAUSE, MC_ABILITY_SUPPORTED_NO);
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_STOP, MC_ABILITY_SUPPORTED_YES);
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_NEXT, MC_ABILITY_SUPPORTED_NO);
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_PREV, MC_ABILITY_SUPPORTED_YES);
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_FAST_FORWARD, MC_ABILITY_SUPPORTED_NO);
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_REWIND, MC_ABILITY_SUPPORTED_YES);
+               ret = mc_server_set_playback_ability(g_mc_server, MC_PLAYBACK_ACTION_TOGGLE_PLAY_PAUSE, MC_ABILITY_SUPPORTED_NO);
+               ret = mc_server_update_playback_ability(g_mc_server);
+               if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+                       g_print("Fail to mc_server_update_playback_ability. err=%d", ret);
+                       return FALSE;
+               }
+               break;
+       case 8:
+               if (g_ability_support != MC_ABILITY_SUPPORTED_YES)
+                       g_ability_support = MC_ABILITY_SUPPORTED_YES;
+               else
+                       g_ability_support = MC_ABILITY_SUPPORTED_NO;
+
+               ret = mc_server_set_shuffle_ability(g_mc_server, g_ability_support);
+               if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+                       g_print("Fail to mc_server_set_shuffle_ability. err=%d", ret);
+                       return FALSE;
+               }
+               break;
+       case 9:
+               if (g_ability_support != MC_ABILITY_SUPPORTED_YES)
+                       g_ability_support = MC_ABILITY_SUPPORTED_YES;
+               else
+                       g_ability_support = MC_ABILITY_SUPPORTED_NO;
+
+               ret = mc_server_set_repeat_ability(g_mc_server, g_ability_support);
+               if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+                       g_print("Fail to mc_server_set_repeat_ability. err=%d", ret);
+                       return FALSE;
+               }
+               break;
        default:
                g_print(" == unknown type!\n");
                return TRUE;
@@ -722,6 +782,10 @@ static void display_update_info_menu(void)
        g_print("3. update server shuffle mode \n");
        g_print("4. update server repeate mode \n");
        g_print("5. update playlist \n");
+       g_print("6. update icon uri \n");
+       g_print("7. update playback ability \n");
+       g_print("8. update shuffle ability \n");
+       g_print("9. update repeat ability \n");
        g_print("0. back \n");
        g_print("----------------------------------------------------\n");
        g_print("====================================================\n");
@@ -737,8 +801,9 @@ static void display_set_info_menu(void)
        g_print("1. set server playback state\n");
        g_print("2. set server playback position \n");
        g_print("3. set server media id \n");
-       g_print("4. set server metadata name\n");
-       g_print("5. set server metadata value\n");
+       g_print("4. set server content type \n");
+       g_print("5. set server metadata name\n");
+       g_print("6. set server metadata value\n");
        g_print("0. back \n");
        g_print("----------------------------------------------------\n");
        g_print("====================================================\n");
@@ -808,6 +873,14 @@ void _interpret_update_info_menu(char *cmd)
                        _update_info(4);
                else if (!strncmp(cmd, "5", len))
                        _update_info(5);
+               else if (!strncmp(cmd, "6", len))
+                       _update_info(6);
+               else if (!strncmp(cmd, "7", len))
+                       _update_info(7);
+               else if (!strncmp(cmd, "8", len))
+                       _update_info(8);
+               else if (!strncmp(cmd, "9", len))
+                       _update_info(9);
                else if (!strncmp(cmd, "0", len))
                        reset_current_menu_state();
        } else {
@@ -827,8 +900,10 @@ void _interpret_set_info_menu(char *cmd)
                else if (!strncmp(cmd, "3", len))
                        g_menu_set_state = CURRENT_STATE_SET_ITEM_ID;
                else if (!strncmp(cmd, "4", len))
-                       g_menu_set_state = CURRENT_STATE_SET_METADATA_NAME;
+                       g_menu_set_state = CURRENT_STATE_SET_CONTENT_TYPE;
                else if (!strncmp(cmd, "5", len))
+                       g_menu_set_state = CURRENT_STATE_SET_METADATA_NAME;
+               else if (!strncmp(cmd, "6", len))
                        g_menu_set_state = CURRENT_STATE_SET_METADATA_VALUE;
                else if (!strncmp(cmd, "0", len)) {
                        reset_current_menu_state();
@@ -904,6 +979,7 @@ static void interpret_cmd(char *cmd)
                case CURRENT_STATE_SET_PLAYBACK_STATE:
                case CURRENT_STATE_SET_PLAYBACK_POSITION:
                case CURRENT_STATE_SET_ITEM_ID:
+               case CURRENT_STATE_SET_CONTENT_TYPE:
                case CURRENT_STATE_SET_METADATA_NAME:
                case CURRENT_STATE_SET_METADATA_VALUE:
                        _set_info(g_menu_set_state, cmd);
@@ -1022,6 +1098,7 @@ int main(int argc, char **argv)
        g_shuffle_mode = MC_SHUFFLE_MODE_OFF;
        g_repeat_mode = MC_REPEAT_MODE_OFF;
        g_playlist_mode = MC_PLAYLIST_REMOVED;
+       g_ability_support = MC_ABILITY_SUPPORTED_UNDECIDED;
 
        mainloop = g_main_loop_new(NULL, FALSE);