From: Jiyong Min Date: Tue, 26 Jun 2018 01:18:21 +0000 (+0900) Subject: [ACR-1252] Add to send event, reply and received callbacks X-Git-Tag: submit/tizen/20180706.044046~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c80a9516eba7f85ba8bec7a06af466d4101485cf;p=platform%2Fcore%2Fapi%2Fmedia-controller.git [ACR-1252] Add to send event, reply and received callbacks Change-Id: I22a3f81785f38c77213e854cc47ab8dd152cb282 (cherry picked from commit beeeff22972d6a79c28f905364f028eb52e9486c) --- diff --git a/include/media_controller_client.h b/include/media_controller_client.h index ba080a5..0403f9e 100755 --- a/include/media_controller_client.h +++ b/include/media_controller_client.h @@ -164,14 +164,14 @@ 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 requesting the list of activated servers. + * @brief Called when requesting the list of created servers. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * - * @remarks The callback is called in the dbus event loop. + * @remarks The callback is called in the main 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 activated media controller server. + * @param[in] server_name The app_id of the created media controller server. * @param[in] user_data The user data passed from the mc_client_foreach_server() function * * @return @c true to continue with the next iteration of the loop, @@ -213,10 +213,10 @@ typedef void (*mc_command_reply_received_cb)(const char *server_name, int result * @param[in] request_id The id of the command request * @param[in] result_code The result code of the action * @param[in] data The extra data - * @param[in] user_data The user data passed from the mc_client_send_custom_cmd() function + * @param[in] user_data The user data passed from the mc_client_set_cmd_reply_received_cb() function * * @pre mc_client_send_custom_cmd() - * @pre mc_client_set_cmd_reply_cb() + * @pre mc_client_set_cmd_reply_received_cb() * * @see mc_client_send_custom_cmd() */ @@ -264,6 +264,30 @@ typedef bool (*mc_subscribed_server_cb)(const char *server_name, void *user_data */ typedef void (*mc_playlist_updated_cb)(const char *server_name, mc_playlist_update_mode_e mode, const char *playlist_name, mc_playlist_h playlist, void *user_data); +/** + * @brief Called when receiving custom event of media controller servers. + * @since_tizen 4.0 + * + * @remarks The callback is called in the dbus event loop. The @a data should be released using bundle_free(). \n + * The @a server_name, @a request_id and @a event should not be released by the application. \n + * The @a server_name, @a request_id and @a event can be used only in the callback. To use outside, make a copy. + * + * @param[in] server_name The app_id of the subscribed media controller server. + * @param[in] request_id The id of the custom event request + * @param[in] event The name of the custom event + * @param[in] data The data can include other information associated with the event + * @param[in] user_data The user data passed from the mc_client_set_custom_event_received_cb() function + * + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * + * @pre mc_client_set_custom_event_received_cb() + * + * @see mc_client_set_custom_event_received_cb() + * @see mc_client_unset_custom_event_received_cb() + */ +typedef void (*mc_client_custom_event_received_cb)(const char *server_name, const char *request_id, const char *event, bundle *data, void *user_data); + /** * @brief Creates a media controller client. * @details The media controller client binds the latest media controller server when handlers are created. @@ -794,6 +818,82 @@ int mc_client_set_playlist_updated_cb(mc_client_h client, mc_playlist_updated_cb */ int mc_client_unset_playlist_updated_cb(mc_client_h client); +/** + * @brief Sets the callback for receiving the custom event from a media controller server. + * @since_tizen 4.0 + * + * @privlevel public + * @privilege %http://tizen.org/privilege/mediacontroller.client + * + * @param[in] client The handle to media controller client + * @param[in] callback The callback to be invoked when the media controller client receives custom event from a media controller server. + * @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_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_client_create() + * @see mc_client_custom_event_received_cb() + * @see mc_client_unset_custom_event_received_cb() + * @see mc_client_send_event_reply() + * @see mc_client_destroy() + */ +int mc_client_set_custom_event_received_cb(mc_client_h client, mc_client_custom_event_received_cb callback, void *user_data); + +/** + * @brief Unsets the callback for receiving the custom event from a media controller server. + * @since_tizen 4.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 server handle by calling mc_server_create(). + * @see mc_client_create() + * @see mc_client_custom_event_received_cb() + * @see mc_client_set_custom_event_received_cb() + * @see mc_client_destroy() + */ +int mc_client_unset_custom_event_received_cb(mc_client_h client); + +/** + * @brief Replies with the result of the requested event to the media controller server. + * @since_tizen 4.0 + * + * @privlevel public + * @privilege %http://tizen.org/privilege/mediacontroller.client + * + * @remarks The media controller client get the @a server_name and @a request_id through the mc_client_custom_event_received_cb(). + * If @a request_id is not null there, the media controller client should send the reply to the media controller server with the @a request_id. \n + * If @a request_id is null, this function will return #MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER. + * + * @param[in] client The handle to the media controller client + * @param[in] server_name The app_id of the media controller server + * @param[in] request_id The id of the event request, received in the mc_client_set_custom_event_received_cb() function. + * @param[in] result_code The result code of custom event + * @param[in] data The extra data + * @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_client_create() + * @see mc_client_set_custom_event_received_cb() + * @see mc_client_unset_custom_event_received_cb() + * @see mc_client_destroy() + */ +int mc_client_send_event_reply(mc_client_h client, const char *server_name, const char *request_id, int result_code, bundle *data); + /** * @brief Subscribes media controller server for monitoring status. * @details If media controller client subscribe media controller server, \n @@ -997,6 +1097,9 @@ int mc_client_destroy_metadata(mc_metadata_h metadata) TIZEN_DEPRECATED_API; * * @remarks The @a server_name should be released using free(). \n * If there is no activated media controller server, return value of the server name is NULL. \n + * Before a media controller server sets the playback state to #MC_PLAYBACK_STATE_PLAYING, the @a server_state is #MC_SERVER_STATE_NONE. + * After a media controller server sets the playback state to #MC_PLAYBACK_STATE_PLAYING, the @a server_state is #MC_SERVER_STATE_ACTIVATE. + * After a media controller server is destroyed, @a server_state is #MC_SERVER_STATE_DEACTIVATE. * * @param[in] client The handle to the media controller client * @param[out] server_name The app_id of the latest media controller server @@ -1096,14 +1199,17 @@ 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 Retrieves all activated Server. + * @brief Retrieves all created servers. + * @details This function gets all created media controller servers. + * The callback function will be invoked for every created media controller server. + * If there are no media controller servers, the callback will not be invoked. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * * @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 list of the registered media controller server created completely. + * @param[in] callback The callback function to be invoked, will be called for each server * @param[in] user_data The user data to be passed to the callback function * @return @c 0 on success, * otherwise a negative error value diff --git a/include/media_controller_db.h b/include/media_controller_db.h index 7863fa2..f791ed1 100755 --- a/include/media_controller_db.h +++ b/include/media_controller_db.h @@ -24,6 +24,7 @@ int mc_db_disconnect(void *db_handle); int mc_db_create_server_table(void *handle, const char *server_name); 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_whole_metadata(void *handle, const char *server_name, @@ -31,6 +32,7 @@ int mc_db_update_whole_metadata(void *handle, const char *server_name, 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_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); int mc_db_get_server_state(void *handle, const char *server_name, mc_server_state_e *state); @@ -42,8 +44,11 @@ int mc_db_get_foreach_playlist(void *handle, const char *server_name, mc_playlis 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); int mc_db_delete_server_address_from_server_list(void *db_handle, const char *address); +int mc_db_insert_client_address_into_client_list(void *db_handle, const char *address); +int mc_db_delete_client_address_from_client_list(void *db_handle, const char *address); int mc_db_foreach_server_list(void *handle, mc_activated_server_cb callback, void *user_data); +int mc_db_foreach_client_list(void *handle, mc_activated_client_cb callback, void *user_data); int mc_db_update_server_and_playback_state(void *handle, const char *server_name, mc_server_state_e server_state, mc_playback_states_e playback_state); int mc_db_update_latest_server_table(void *handle, const char *server_name); int mc_db_remove_playlist(void *handle, const char *server_name, const char *playlist_name); diff --git a/include/media_controller_private.h b/include/media_controller_private.h index 2066a36..4d0e630 100755 --- a/include/media_controller_private.h +++ b/include/media_controller_private.h @@ -119,6 +119,7 @@ extern "C" { #define MC_DB_TABLE_SERVER_LIST "server_list" #define MC_DB_TABLE_LATEST_SERVER "latest_server" #define MC_DB_TABLE_PLAYLIST "server_playlist" +#define MC_DB_TABLE_CLIENT_LIST "client_list" #define SQLITE3_SAFE_FREE(sql_string) {if (sql_string) { sqlite3_free(sql_string); sql_string = NULL; } } #define SQLITE3_FINALIZE(x) {if (x != NULL) sqlite3_finalize(x); } @@ -168,6 +169,8 @@ extern "C" { #define MC_DBUS_SIGNAL_NAME_PLAYBACK_PLAYLIST "pb_playlist" #define MC_DBUS_SIGNAL_NAME_CUSTOM_COMMAND "custom_command" #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_COMMAND_PLAYBACKSTATE "_pb_state_cmd_" @@ -180,8 +183,13 @@ extern "C" { #define MC_COMMAND_CUSTOMACTION "_custom_action_" #define MC_COMMAND_CMDREPLY "_cmd_reply_" +#define MC_EVENT_CUSTOM "_custom_event_" +#define MC_EVENT_REPLY "_event_reply_" + + #define MC_DB_CMD_CREATE_SERVER "DB_CMD_CREATE_SERVER" /* Create New Server Table*/ #define MC_DB_CMD_UPDATE_SERVER_LIST "DB_CMD_UPDATE_SERVER_LIST" /* Update Server Name*/ +#define MC_DB_CMD_UPDATE_CLIENT_LIST "DB_CMD_UPDATE_CLIENT_LIST" /* Update Client Name*/ #define MC_DB_CMD_UPDATE_PLAYBACK "DB_CMD_UPDATE_PLAYBACK" /* Update Server Playback info*/ #define MC_DB_CMD_UPDATE_STATE_PLAYBACK "DB_CMD_UPDATE_STATE_PLAYBACK" /* Update Server State and Playback state*/ #define MC_DB_CMD_UPDATE_META "DB_CMD_UPDATE_META" /* Update Server Meta info*/ @@ -192,6 +200,7 @@ extern "C" { #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*/ +#define MC_DB_CMD_REMOVE_CLIENT_LIST "DB_CMD_REMOVE_CLIENT_LIST" /* Remove Client from Client List*/ #define DEFAULT_USER_UID 5001 /* owner */ @@ -258,6 +267,7 @@ typedef struct { media_controller_receiver_s custom_cmd_reciever; media_controller_receiver_s play_playlist_reciever; media_controller_receiver_s custom_command_reciever; + media_controller_receiver_s event_reply_receiver; } media_controller_server_s; typedef struct { @@ -277,6 +287,7 @@ typedef struct { media_controller_receiver_s reply_cb; media_controller_receiver_s playlist_cb; media_controller_receiver_s cmd_reply_cb; + media_controller_receiver_s custom_event_cb; } media_controller_client_s; typedef struct { diff --git a/include/media_controller_server.h b/include/media_controller_server.h index be8d52a..d3cbf8c 100755 --- a/include/media_controller_server.h +++ b/include/media_controller_server.h @@ -211,6 +211,49 @@ typedef void (*mc_server_playlist_cmd_received_cb)(const char* client_name, cons */ typedef void (*mc_server_custom_cmd_received_cb)(const char* client_name, const char *request_id, const char *command, bundle *data, void *user_data); +/** + * @brief Called when requesting the list of created clients. + * @since_tizen 4.0 + * + * @remarks The callback is called in the main loop. \n + * The @a client_name should not be released by the application. \n + * The @a client_name can be used only in the callback. To use outside, make a copy. + * + * @param[in] client_name The app_id of the created media controller client. + * @param[in] user_data The user data passed from the mc_client_foreach_server() function + * + * @return @c true to continue with the next iteration of the loop, + * otherwise @c false to break out of the loop + * + * @pre mc_server_foreach_client() + * + * @see mc_server_foreach_client() + */ +typedef bool (*mc_activated_client_cb)(const char *client_name, void *user_data); + +/** + * @brief Called when the result of the event from the client is received. + * @since_tizen 4.0 + * + * @remarks The callback is called in the dbus event loop. @a data should be released using bundle_free(). \n + * The @a client_name and @a request_id should not be released by the application. \n + * The @a client_name and @a request_id can be used only in the callback. To use outside, make a copy. + * + * @param[in] client_name The app_id of the media controller client which sent the reply. It can be used only in the callback. To use outside, make a copy. + * @param[in] request_id The id of the event request + * @param[in] result_code The result code of the event + * @param[in] data The extra data + * @param[in] user_data The user data passed from the mc_server_set_event_reply_received_cb() function + * + * @pre mc_server_send_custom_event() + * @pre mc_server_set_event_reply_received_cb() + * + * @see mc_server_send_custom_event() + * @see mc_server_set_event_reply_received_cb() + * @see mc_server_unset_event_reply_received_cb() + */ +typedef void (*mc_server_event_reply_received_cb)(const char *client_name, const char *request_id, int result_code, bundle *data, void *user_data); + /** * @brief Creates a media controller server. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif @@ -798,6 +841,107 @@ int mc_server_unset_custom_cmd_received_cb(mc_server_h server); */ int mc_server_send_cmd_reply(mc_server_h server, const char *client_name, const char *request_id, int result_code, bundle *data); +/** + * @brief Retrieves all created clients. + * @details This function gets all created media controller clients. + * The callback function will be invoked for every created media controller client. + * If there are no media controller clients, the callback will not be invoked. + * @since_tizen 4.0 + * + * @privlevel public + * @privilege %http://tizen.org/privilege/mediacontroller.server + * + * @param[in] server The handle to media controller server + * @param[in] callback The callback function to be invoked, will be called for each client + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #MEDIA_CONTROLLER_ERROR_NONE Successful + * @retval #MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIA_CONTROLLER_ERROR_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_activated_client_cb() + * @see mc_server_destroy() + */ +int mc_server_foreach_client(mc_server_h server, mc_activated_client_cb callback, void *user_data); + +/** + * @brief Sends the customized event with the bundle data. + * @details If the event is needed in the client, this function should be called. @a data is a bundle. + * @since_tizen 4.0 + * + * @privlevel public + * @privilege %http://tizen.org/privilege/mediacontroller.server + * + * @remarks The @a request_id should be released using free().\n + * If the @a request_id is null, the client will not send the reply of the custom event. + * + * @param[in] server The handle to media controller server + * @param[in] client_name The name of the client which receive the event + * @param[in] event The name of the event + * @param[in] data The data can include other information associated with the event + * @param[out] request_id The id of the event request, it will be passed to the mc_server_event_reply_received_cb() 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_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_event_reply_received_cb() + * @see mc_server_set_event_reply_received_cb() + * @see mc_server_destroy() + */ +int mc_server_send_custom_event(mc_server_h server, const char *client_name, const char *event, bundle *data, char **request_id); + +/** + * @brief Sets the callback for receiving the result of the event from the media controller client. + * @details The media controller server which calls this function will receive the result of the event from all media controller clients. + * @since_tizen 4.0 + * + * @privlevel public + * @privilege %http://tizen.org/privilege/mediacontroller.server + * + * @param[in] server The handle to the media controller server + * @param[in] callback The callback to be invoked when the reply is received + * @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_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_unset_event_reply_received_cb() + * @see mc_server_destroy() + */ +int mc_server_set_event_reply_received_cb(mc_server_h server, mc_server_event_reply_received_cb callback, void *user_data); + +/** + * @brief Unsets the callback for receiving event reply of the media controller client. + * @since_tizen 4.0 + * + * @privlevel public + * @privilege %http://tizen.org/privilege/mediacontroller.server + * + * @param[in] server The handle to the 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 client handle by calling mc_client_create(). + * @see mc_server_create() + * @see mc_server_set_event_reply_received_cb() + * @see mc_server_destroy() + */ +int mc_server_unset_event_reply_received_cb(mc_server_h server); + /** * @brief Destroys media controller server. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif diff --git a/src/media_controller_client.c b/src/media_controller_client.c index fb6791b..92f8626 100755 --- a/src/media_controller_client.c +++ b/src/media_controller_client.c @@ -229,6 +229,48 @@ static void __client_cmd_reply_received_cb(const char *interface_name, const cha g_strfreev(params); } +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) +{ + gchar **params = NULL; + int enc_size = 0; + char *sender = NULL; + char *command = NULL; + bundle *bundle_data = NULL; + + media_controller_receiver_s *receiver = (media_controller_receiver_s *)user_data; + mc_retm_if(receiver == NULL, "reciever is NULL"); + + mc_client_custom_event_received_cb callback = receiver->callback; + mc_retm_if(receiver->callback == NULL, "custom_event_received_cb is NULL"); + + mc_debug("__client_custom_event_received_cb(%s, %s, %s, %llu, %p)", interface_name, signal_name, message, request_id, user_data); + + params = g_strsplit(message, MC_STRING_DELIMITER, 0); + mc_retm_if(params == NULL, "invalid custom data"); + + if (params[0]) + sender = strdup(params[0]); + + if (mc_util_get_command_available(MC_PRIV_TYPE_CLIENT, sender, MC_EVENT_CUSTOM, params[1]) != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Error permission denied"); + MC_SAFE_FREE(sender); + g_strfreev(params); + return; + } + + command = strdup(params[1]); + enc_size = atoi(params[2]); + if (enc_size > 0) + bundle_data = bundle_decode((bundle_raw *)params[3], enc_size); + + callback(sender, request_id, command, bundle_data, receiver->user_data); + + MC_SAFE_FREE(sender); + MC_SAFE_FREE(command); + + g_strfreev(params); +} + static int __mc_client_create(media_controller_client_s **mc_client) { int ret = MEDIA_CONTROLLER_ERROR_NONE; @@ -454,6 +496,13 @@ int mc_client_create(mc_client_h *client) return ret; } + ret = mc_db_insert_client_address_into_client_list(mc_client->db_handle, mc_client->client_name); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("fail mc_db_insert_server_address_into_table [%d]", ret); + __mc_client_destroy(mc_client); + return ret; + } + *client = (mc_client_h)mc_client; mc_debug_fleave(); @@ -1549,6 +1598,73 @@ int mc_client_send_custom_cmd(mc_client_h client, const char *server_name, const return ret; } +int mc_client_set_custom_event_received_cb(mc_client_h client, mc_client_custom_event_received_cb callback, void *user_data) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + media_controller_client_s *mc_client = (media_controller_client_s *)client; + + mc_retvm_if(mc_client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + mc_retvm_if(callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "callback is NULL"); + + mc_client->custom_event_cb.callback = callback; + mc_client->custom_event_cb.user_data = user_data; + + char *interface_name = mc_util_get_interface_name(MC_CLIENT, mc_client->client_name); + ret = mc_ipc_register_listener(&mc_client->listeners, mc_client->dconn, interface_name, MC_DBUS_SIGNAL_NAME_CUSTOM_EVENT, + __client_custom_event_received_cb, (void *)&(mc_client->custom_event_cb)); + + MC_SAFE_FREE(interface_name); + + return ret; +} + +int mc_client_unset_custom_event_received_cb(mc_client_h client) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + media_controller_client_s *mc_client = (media_controller_client_s *)client; + + mc_retvm_if(mc_client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + + char *interface_name = mc_util_get_interface_name(MC_CLIENT, mc_client->client_name); + ret = mc_ipc_unregister_listener(&mc_client->listeners, mc_client->dconn, interface_name, MC_DBUS_SIGNAL_NAME_CUSTOM_EVENT); + + mc_client->custom_event_cb.callback = NULL; + mc_client->custom_event_cb.user_data = NULL; + + MC_SAFE_FREE(interface_name); + + return ret; +} + +int mc_client_send_event_reply(mc_client_h client, const char *server_name, const char *request_id, int result_code, bundle *data) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + char *message = NULL; + char *bundle_str = NULL; + 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(!MC_STRING_VALID(server_name), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "server_name is NULL"); + mc_retvm_if(!MC_STRING_VALID(request_id), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "request_id is NULL"); + + ret = mc_util_bundle_to_string(data, &bundle_str); + mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error when make string from bundle"); + + message = g_strdup_printf("%s%s%d%s%s", mc_client->client_name, MC_STRING_DELIMITER, result_code, MC_STRING_DELIMITER, bundle_str); + MC_SAFE_G_FREE(bundle_str); + mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "Error when making message"); + + char *interface_name = mc_util_get_interface_name(MC_SERVER, server_name); + ret = mc_ipc_send_reply(mc_client->dconn, NULL, interface_name, MC_DBUS_SIGNAL_NAME_EVENT_REPLY, message, request_id); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("Error mc_ipc_send_message [%d]", ret); + + MC_SAFE_G_FREE(message); + MC_SAFE_G_FREE(interface_name); + + return ret; +} + int mc_client_destroy(mc_client_h client) { int ret = MEDIA_CONTROLLER_ERROR_NONE; @@ -1571,6 +1687,10 @@ int mc_client_destroy(mc_client_h client) if (ret != MEDIA_CONTROLLER_ERROR_NONE) mc_error("Error mc_ipc_unregister_all_listener [%d]", ret); + ret = mc_db_delete_client_address_from_client_list(mc_client->db_handle, mc_client->client_name); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("fail mc_db_delete_client_address_from_client_list [%d]", ret); + /*Send Disconnection Msg to Server*/ ret = mc_ipc_send_message_to_server(MC_MSG_SERVER_DISCONNECTION, MC_PRIV_TYPE_CLIENT, MC_SERVER_DISCONNECTION_MSG); if (ret != MEDIA_CONTROLLER_ERROR_NONE) diff --git a/src/media_controller_db.c b/src/media_controller_db.c index 416e4eb..42b2670 100755 --- a/src/media_controller_db.c +++ b/src/media_controller_db.c @@ -644,6 +644,40 @@ int mc_db_delete_server_address_from_server_list(void *handle, const char *addre return ret; } +int mc_db_insert_client_address_into_client_list(void *handle, const char *address) +{ + 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(!MC_STRING_VALID(address), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "invalid address"); + + sql_str = g_strdup_printf("%s%s%s", MC_DB_CMD_UPDATE_CLIENT_LIST, MC_STRING_DELIMITER, address); + + ret = __mc_db_update_db(handle, MC_PRIV_TYPE_CLIENT, sql_str); + + MC_SAFE_FREE(sql_str); + + return ret; +} + +int mc_db_delete_client_address_from_client_list(void *handle, const char *address) +{ + 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(!MC_STRING_VALID(address), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "invalid address"); + + sql_str = g_strdup_printf("%s%s%s", MC_DB_CMD_REMOVE_CLIENT_LIST, MC_STRING_DELIMITER, address); + + ret = __mc_db_update_db(handle, MC_PRIV_TYPE_CLIENT, sql_str); + + MC_SAFE_FREE(sql_str); + + return ret; +} + int mc_db_disconnect(void *handle) { int ret = MEDIA_CONTROLLER_ERROR_NONE; @@ -740,6 +774,49 @@ int mc_db_check_server_table_exist(void *handle, const char *server_name, bool * return MEDIA_CONTROLLER_ERROR_NONE; } +int mc_db_check_client_table_exist(void *handle, const char *client_name, bool *exist) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + char *sql_str = NULL; + sqlite3_stmt *stmt = NULL; + int count = 0; + + mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + mc_retvm_if(client_name == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "server_name is NULL"); + + sql_str = sqlite3_mprintf("SELECT COUNT(*) FROM '%q' WHERE client_name='%q'", MC_DB_TABLE_CLIENT_LIST, client_name); + mc_retvm_if(!MC_STRING_VALID(sql_str), MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "SQL string is null"); + + ret = sqlite3_prepare_v2(handle, sql_str, strlen(sql_str), &stmt, NULL); + if (SQLITE_OK != ret) { + mc_error("prepare error [%s]", sqlite3_errmsg(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(handle)); + SQLITE3_FINALIZE(stmt); + SQLITE3_SAFE_FREE(sql_str); + return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + + count = sqlite3_column_int(stmt, 0); + + mc_debug("table count [%d]", count); + + if (count > 0) + *exist = TRUE; + else + *exist = FALSE; + + SQLITE3_FINALIZE(stmt); + SQLITE3_SAFE_FREE(sql_str); + + return MEDIA_CONTROLLER_ERROR_NONE; +} + int mc_db_foreach_server_list(void *handle, mc_activated_server_cb callback, void *user_data) { int ret = MEDIA_CONTROLLER_ERROR_NONE; @@ -784,6 +861,50 @@ int mc_db_foreach_server_list(void *handle, mc_activated_server_cb callback, voi return MEDIA_CONTROLLER_ERROR_NONE; } +int mc_db_foreach_client_list(void *handle, mc_activated_client_cb callback, void *user_data) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + sqlite3 *db_handle = (sqlite3 *)handle; + char *sql_str = NULL; + sqlite3_stmt *stmt = NULL; + + mc_retvm_if(db_handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + + sql_str = sqlite3_mprintf("SELECT client_name FROM '%q';", MC_DB_TABLE_CLIENT_LIST); + 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("[No-Error] There is no client list [%s]", sqlite3_errmsg(db_handle)); + SQLITE3_FINALIZE(stmt); + SQLITE3_SAFE_FREE(sql_str); + return MEDIA_CONTROLLER_ERROR_NONE; + } + + while (SQLITE_ROW == ret) { + char *client_name = NULL; + client_name = strdup((char *)sqlite3_column_text(stmt, 0)); + if (callback(client_name, user_data) == false) { + MC_SAFE_FREE(client_name); + break; + } + MC_SAFE_FREE(client_name); + + ret = sqlite3_step(stmt); + } + + SQLITE3_FINALIZE(stmt); + SQLITE3_SAFE_FREE(sql_str); + + return MEDIA_CONTROLLER_ERROR_NONE; +} + int mc_db_update_server_and_playback_state(void *handle, const char *server_name, mc_server_state_e server_state, mc_playback_states_e playback_state) { int ret = MEDIA_CONTROLLER_ERROR_NONE; diff --git a/src/media_controller_ipc.c b/src/media_controller_ipc.c index c044539..6bb43f4 100755 --- a/src/media_controller_ipc.c +++ b/src/media_controller_ipc.c @@ -53,17 +53,16 @@ static void __mc_ipc_signal_cb(GDBusConnection *connection, mc_debug("__mc_ipc_signal_cb Received :"); gchar *message = NULL; - gchar * request_id = NULL; + gchar *request_id = NULL; - g_variant_get(parameters, "(s&s)", &request_id, &message); + g_variant_get(parameters, "(&s&s)", &request_id, &message); if (!message) { mc_error("g_variant_get() fail"); return; } - if ((request_id != NULL) && (!g_strcmp0(request_id, DEFAULT_REQ_ID))) { + if ((request_id != NULL) && (!g_strcmp0(request_id, DEFAULT_REQ_ID))) request_id = NULL; - } char *key = __make_key_for_map(interface_name, signal_name); if (key == NULL) { @@ -80,6 +79,7 @@ static void __mc_ipc_signal_cb(GDBusConnection *connection, break; } } + MC_SAFE_FREE(key); } diff --git a/src/media_controller_server.c b/src/media_controller_server.c index 9dfe97e..3493748 100755 --- a/src/media_controller_server.c +++ b/src/media_controller_server.c @@ -400,6 +400,38 @@ static void __server_custom_cmd_cb(const char *interface_name, const char *signa g_strfreev(params); } +static void __server_event_reply_received_cb(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data) +{ + gchar **params = NULL; + int result_code = 0; + int enc_size = 0; + bundle *bundle_data = NULL; + + media_controller_receiver_s *reciever = (media_controller_receiver_s *)user_data; + 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_debug("__server_event_reply_received_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 custom data"); + + if (params[1] != NULL) + mc_retm_if(MEDIA_CONTROLLER_ERROR_NONE != mc_safe_strtoi(params[1], &result_code), "getting result_code is failed"); + + if (params[2] != NULL) + mc_retm_if(MEDIA_CONTROLLER_ERROR_NONE != mc_safe_strtoi(params[2], &enc_size), "getting message is failed"); + + if (enc_size > 0) + bundle_data = bundle_decode((bundle_raw *)params[3], enc_size); + + callback(params[0], request_id, result_code, bundle_data, reciever->user_data); + + g_strfreev(params); +} + static int __mc_server_current_is_latest(media_controller_server_s *mc_server, bool *is_latest) { int ret = MEDIA_CONTROLLER_ERROR_NONE; @@ -468,6 +500,37 @@ static int __mc_server_send_message(media_controller_server_s *mc_server, const return ret; } +static int __mc_server_send_event(mc_server_h server, const char *client_name, const char *command_type, const char *event, const char *signal_name, const char *message, char **request_id) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + media_controller_server_s *mc_server = (media_controller_server_s *)server; + bool exist_server = FALSE; + char *interface_name = NULL; + + mc_retvm_if(mc_server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + mc_retvm_if(!MC_STRING_VALID(client_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_client_table_exist(mc_server->db_handle, client_name, &exist_server); + mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_db_check_client_table_exist [%d]", ret); + mc_retvm_if(exist_server == FALSE, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Error Invalid client_name"); + + ret = mc_util_set_command_available(MC_PRIV_TYPE_SERVER, mc_server->server_name, command_type, event); + mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error mc_util_set_command_available [%d]", ret); + + interface_name = mc_util_get_interface_name(MC_CLIENT, client_name); + + ret = mc_ipc_send_message(mc_server->dconn, NULL, interface_name, signal_name, message, request_id); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("Error mc_ipc_send_message [%d]", ret); + + MC_SAFE_G_FREE(interface_name); + + return ret; +} + int mc_server_set_playback_state(mc_server_h server, mc_playback_states_e state) { media_controller_server_s *mc_server = (media_controller_server_s *)server; @@ -1305,6 +1368,83 @@ int mc_server_send_cmd_reply(mc_server_h server, const char *client_name, const return ret; } +int mc_server_foreach_client(mc_server_h server, mc_activated_client_cb callback, void *user_data) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + media_controller_server_s *mc_server = (media_controller_server_s *)server; + + mc_retvm_if(mc_server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + mc_retvm_if(callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "callback is NULL"); + + ret = mc_db_foreach_client_list(mc_server->db_handle, callback, user_data); + + return ret; +} + +int mc_server_send_custom_event(mc_server_h server, const char *client_name, const char *event, bundle *data, char **request_id) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + char *message = NULL; + char *bundle_str = NULL; + 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(!MC_STRING_VALID(client_name), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid client_name"); + mc_retvm_if(event == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "event is NULL"); + + ret = mc_util_bundle_to_string(data, &bundle_str); + mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "Error when make string from bundle"); + + message = g_strdup_printf("%s%s%s%s%s", mc_server->server_name, MC_STRING_DELIMITER, event, MC_STRING_DELIMITER, bundle_str); + MC_SAFE_G_FREE(bundle_str); + mc_retvm_if(message == NULL, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "Error when making message"); + + ret = __mc_server_send_event(server, client_name, MC_EVENT_CUSTOM, event, MC_DBUS_SIGNAL_NAME_CUSTOM_EVENT, message, request_id); + + MC_SAFE_G_FREE(message); + + return ret; +} + +int mc_server_set_event_reply_received_cb(mc_server_h server, mc_server_event_reply_received_cb callback, void *user_data) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + media_controller_server_s *mc_server = (media_controller_server_s *)server; + + mc_retvm_if(mc_server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + mc_retvm_if(callback == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "callback is NULL"); + mc_retvm_if(mc_server->event_reply_receiver.callback != NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "callback is already set"); + + mc_server->event_reply_receiver.callback = callback; + mc_server->event_reply_receiver.user_data = user_data; + + char *interface_name = mc_util_get_interface_name(MC_SERVER, mc_server->server_name); + ret = mc_ipc_register_listener(&mc_server->listeners, mc_server->dconn, interface_name, MC_DBUS_SIGNAL_NAME_EVENT_REPLY, + __server_event_reply_received_cb, (void *)&(mc_server->event_reply_receiver)); + + MC_SAFE_FREE(interface_name); + + return ret; +} + +int mc_server_unset_event_reply_received_cb(mc_server_h server) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + media_controller_server_s *mc_server = (media_controller_server_s *)server; + + mc_retvm_if(mc_server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); + + char *interface_name = mc_util_get_interface_name(MC_SERVER, mc_server->server_name); + ret = mc_ipc_unregister_listener(&mc_server->listeners, mc_server->dconn, interface_name, MC_DBUS_SIGNAL_NAME_EVENT_REPLY); + + mc_server->event_reply_receiver.callback = NULL; + mc_server->event_reply_receiver.user_data = NULL; + + MC_SAFE_FREE(interface_name); + + return ret; +} + int mc_server_create(mc_server_h *server) { int ret = MEDIA_CONTROLLER_ERROR_NONE; diff --git a/svc/media_controller_db_util.c b/svc/media_controller_db_util.c index 773fc32..ddcaf50 100755 --- a/svc/media_controller_db_util.c +++ b/svc/media_controller_db_util.c @@ -124,6 +124,19 @@ static int __mc_create_server_list_table(sqlite3 *handle) return ret; } +static int __mc_create_client_list_table(sqlite3 *handle) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + char *sql_str = NULL; + + sql_str = sqlite3_mprintf("CREATE TABLE IF NOT EXISTS %s (client_name TEXT PRIMARY KEY);", MC_DB_TABLE_CLIENT_LIST); + + ret = mc_db_util_update_db(handle, sql_str); + + SQLITE3_SAFE_FREE(sql_str); + return ret; +} + static int __mc_create_playlist_table(sqlite3 *handle) { int ret = MEDIA_CONTROLLER_ERROR_NONE; @@ -331,6 +344,9 @@ int mc_db_util_create_tables(void *handle) ret = __mc_create_server_list_table(db_handle); mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "create server_list table failed!err= [%d]", ret); + ret = __mc_create_client_list_table(db_handle); + mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "create client_list table failed!err= [%d]", ret); + ret = __mc_create_playlist_table(db_handle); mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, ret, "create playlist table failed!err= [%d]", ret); @@ -494,6 +510,9 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size) } else if (strncmp(MC_DB_CMD_UPDATE_SERVER_LIST, params[0], strlen(MC_DB_CMD_UPDATE_SERVER_LIST)) == 0) { sql_str = sqlite3_mprintf("INSERT INTO '%q' (server_name) VALUES ('%q');", MC_DB_TABLE_SERVER_LIST, params[1]); + } else if (strncmp(MC_DB_CMD_UPDATE_CLIENT_LIST, params[0], strlen(MC_DB_CMD_UPDATE_CLIENT_LIST)) == 0) { + sql_str = sqlite3_mprintf("INSERT INTO '%q' (client_name) VALUES ('%q');", MC_DB_TABLE_CLIENT_LIST, params[1]); + } else if (strncmp(MC_DB_CMD_UPDATE_STATE_PLAYBACK, params[0], strlen(MC_DB_CMD_UPDATE_STATE_PLAYBACK)) == 0) { if (params[2] == NULL || params[3] == NULL) { mc_error("wrong query"); @@ -556,6 +575,9 @@ int mc_db_parse_and_update_db(uid_t uid, const char *data, int data_size) } 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]); + } else if (strncmp(MC_DB_CMD_REMOVE_CLIENT_LIST, params[0], strlen(MC_DB_CMD_REMOVE_CLIENT_LIST)) == 0) { + sql_str = sqlite3_mprintf("DELETE FROM %q WHERE client_name = '%q';", MC_DB_TABLE_CLIENT_LIST, params[1]); + } else if (strncmp(MC_DB_CMD_REMOVE_SERVER, params[0], strlen(MC_DB_CMD_REMOVE_SERVER)) == 0) { sql_str = sqlite3_mprintf("DROP TABLE IF EXISTS '%q'", params[1]); diff --git a/test/client_test/media_controller_client_test.c b/test/client_test/media_controller_client_test.c index f086a84..1c3f89f 100755 --- a/test/client_test/media_controller_client_test.c +++ b/test/client_test/media_controller_client_test.c @@ -204,6 +204,29 @@ void _mc_cmd_reply_received_cb(const char *server_name, const char *request_id, } } +void _mc_custom_event_received_cb(const char *server_name, const char *request_id, const char *event, bundle *data, void *user_data) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + + const char *bundle_key = "key1"; + char *bundle_value = NULL; + + if (data) + bundle_get_str(data, bundle_key, &bundle_value); + + g_print("recieved request_id:[%s] event:[%s] bundle:[%s, %s] from [%s]\n", + request_id, event, bundle_key, bundle_value, server_name); + + bundle *bundle_reply = bundle_create(); + bundle_add_str(bundle_reply, "key1", "result1"); + + ret = mc_client_send_event_reply(g_mc_client, server_name, request_id, 0, bundle_reply); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) + g_print("Fail to mc_client_send_event_reply\n"); + + bundle_free(bundle_reply); +} + static gboolean _create() { g_print("== create \n"); @@ -261,6 +284,9 @@ static gboolean _set_callback() ret = mc_client_set_cmd_reply_received_cb(g_mc_client, _mc_cmd_reply_received_cb, NULL); mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_set_reply_received_cb [%d]", ret); + 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); + mc_debug_fleave(); return ret; @@ -293,6 +319,9 @@ static gboolean _unset_callback() ret = mc_client_unset_cmd_reply_received_cb(g_mc_client); mc_retvm_if(ret != MEDIA_CONTROLLER_ERROR_NONE, FALSE, "Fail to mc_client_unset_reply_received_cb [%d]", ret); + 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); + mc_debug_fleave(); return TRUE; diff --git a/test/server_test/media_controller_server_test.c b/test/server_test/media_controller_server_test.c index 9f29425..1ff5af2 100755 --- a/test/server_test/media_controller_server_test.c +++ b/test/server_test/media_controller_server_test.c @@ -40,6 +40,11 @@ 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; +/* for sending event */ +static char *g_event_name = NULL; +static char *g_client_name = NULL; +static char *g_request_id = NULL; + GMainLoop *mainloop = NULL; #define MAX_STRING_LEN 2048 @@ -53,6 +58,7 @@ enum { CURRENT_STATE_MAIN_MENU, CURRENT_STATE_INFORMATION_SET_MENU, CURRENT_STATE_INFORMATION_UPDATE_MENU, + CURRENT_STATE_SEND_EVENT_MENU, }; enum { @@ -69,6 +75,7 @@ enum { ---------------------------------------------------------------------------*/ int g_menu_state = CURRENT_STATE_MAIN_MENU; int g_menu_set_state = CURRENT_STATE_SET_MODE_NONE; +int g_menu_send_event = 0; /*--------------------------------------------------------------------------- | LOCAL FUNCTION PROTOTYPES: | @@ -346,6 +353,32 @@ void __custom_cmd_received_cb(const char *client_name, const char *request_id, c g_free(bundle_data); } +void __event_reply_received_cb(const char *client_name, const char *request_id, const int result_code, bundle *data, void *user_data) +{ + const char *bundle_key = "key1"; + char *bundle_value = NULL; + + if (data) { + bundle_get_str(data, bundle_key, &bundle_value); + } + + if (g_strcmp0(g_request_id, request_id) != 0) { + g_printf("[recieved event reply] wrong request_id: %s \n", request_id); + } + + g_print("[recieved event reply] request_id:[%s] result:[%d] bundle:[%s, %s] from [%s] \n", + request_id, result_code, bundle_key, bundle_value, client_name); +} + +bool _mc_activated_client_cb(const char *client_name, void *user_data) +{ + char **_client = (char **)user_data; + if (_client == NULL) return FALSE; + *_client = g_strdup(client_name); + g_print("== success activated client_name: %s \n", client_name); + return FALSE; +} + static gboolean _create() { g_print("== create \n"); @@ -414,6 +447,12 @@ static gboolean _set_cb() return FALSE; } + ret = mc_server_set_event_reply_received_cb(g_mc_server, __event_reply_received_cb, NULL); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + g_print("Fail to set mc_server_set_custom_cmd_received_cb"); + return FALSE; + } + g_print("== success set default callback \n"); return TRUE; @@ -550,6 +589,65 @@ static gboolean _update_info(int type) return TRUE; } +static gboolean _send_event(int type, char *cmd) +{ + int ret = MEDIA_CONTROLLER_ERROR_NONE; + bundle *bundle_data = NULL; + + g_print("== send event menu [%d] \n", type); + + switch (type) { + case 1: + if (g_client_name != NULL) { + g_free(g_client_name); + g_client_name = NULL; + } + ret = mc_server_foreach_client(g_mc_server, _mc_activated_client_cb, &g_client_name); + break; + + case 2: + if (g_event_name != NULL) { + g_free(g_event_name); + g_event_name = NULL; + } + g_event_name = g_strdup(cmd); + if (g_event_name == NULL) { + g_print("Fail to set event_name \n"); + return FALSE; + } + g_print("set event_name: %s \n", g_event_name); + break; + + case 3: + if (g_request_id != NULL) { + g_free(g_request_id); + g_request_id = NULL; + } + + bundle_data = bundle_create(); + if (bundle_data == NULL) { + g_print("Fail to create bundle \n"); + return FALSE; + } + bundle_add_str(bundle_data, "key1", "ev_val1"); + + ret = mc_server_send_custom_event(g_mc_server, g_client_name, g_event_name, bundle_data, &g_request_id); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) + g_print("Fail to mc_server_send_custom_event\n"); + + bundle_free(bundle_data); + g_print(" == success send event(req_id:%s) \n", g_request_id); + break; + default: + g_print(" == unknown type!\n"); + return TRUE; + } + + g_print(" == success event menu \n"); + + return TRUE; +} + static gboolean _destroy() { g_print("== destroy \n"); @@ -578,6 +676,12 @@ void quit(void) g_main_loop_quit(mainloop); } +void reset_current_send_menu_state() +{ + g_menu_send_event = 0; + return; +} + void reset_current_set_menu_state() { g_menu_set_state = CURRENT_STATE_SET_MODE_NONE; @@ -624,6 +728,21 @@ static void display_set_info_menu(void) } +static void display_send_menu(void) +{ + g_print("\n"); + g_print("====================================================\n"); + g_print(" media controller test(server): Send event menu\n"); + g_print("----------------------------------------------------\n"); + g_print("1. foreach activated client \n"); + g_print("2. enter event name \n"); + g_print("3. send event \n"); + g_print("0. back \n"); + g_print("----------------------------------------------------\n"); + g_print("====================================================\n"); + +} + static void display_main_menu(void) { g_print("\n"); @@ -634,6 +753,7 @@ static void display_main_menu(void) g_print("2. set default command callback \n"); g_print("3. set information to client \n"); g_print("4. update information to client \n"); + g_print("6. send event to client \n"); g_print("9. destroy media controller server \n"); g_print("0. quit \n"); g_print("----------------------------------------------------\n"); @@ -649,6 +769,8 @@ static void display_menu(void) display_set_info_menu(); else if (g_menu_state == CURRENT_STATE_INFORMATION_UPDATE_MENU) display_update_info_menu(); + else if (g_menu_state == CURRENT_STATE_SEND_EVENT_MENU) + display_send_menu(); else g_print("*** Unknown status.\n"); @@ -700,6 +822,30 @@ void _interpret_set_info_menu(char *cmd) } } +void _interpret_send_menu(char *cmd) +{ + int len = strlen(cmd); + + if (len == 1) { + if (!strncmp(cmd, "1", len)) { + _send_event(1, cmd); + reset_current_send_menu_state(); + display_menu(); + } else if (!strncmp(cmd, "2", len)) { + g_menu_send_event = 2; + } else if (!strncmp(cmd, "3", len)) { + _send_event(3, cmd); + reset_current_send_menu_state(); + display_menu(); + } else if (!strncmp(cmd, "0", len)) { + reset_current_menu_state(); + display_menu(); + } + } else { + g_print("wrong command\n"); + } +} + void _interpret_main_menu(char *cmd) { int len = strlen(cmd); @@ -713,6 +859,8 @@ void _interpret_main_menu(char *cmd) g_menu_state = CURRENT_STATE_INFORMATION_SET_MENU; else if (!strncmp(cmd, "4", len)) g_menu_state = CURRENT_STATE_INFORMATION_UPDATE_MENU; + else if (!strncmp(cmd, "6", len)) + g_menu_state = CURRENT_STATE_SEND_EVENT_MENU; else if (!strncmp(cmd, "9", len)) _destroy(); else if (!strncmp(cmd, "0", len)) @@ -752,6 +900,19 @@ static void interpret_cmd(char *cmd) _interpret_update_info_menu(cmd); display_menu(); break; + case CURRENT_STATE_SEND_EVENT_MENU: + switch (g_menu_send_event) { + case 0: + _interpret_send_menu(cmd); + break; + case 2: + _send_event(g_menu_send_event, cmd); + reset_current_send_menu_state(); + display_menu(); + default: + break; + } + break; default: g_print("Invalid command\n"); }