From: Michal Michalski Date: Tue, 8 Oct 2019 15:10:04 +0000 (+0200) Subject: [utils][mediacontroller] SendEvent() method implementation. X-Git-Tag: submit/tizen/20191009.054725~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6603e9254ce961ce603eeb25b6def60f7579d136;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [utils][mediacontroller] SendEvent() method implementation. [ACR] http://suprem.sec.samsung.net/jira/browse/TWDAPI-209 SendEvent() SendReply() [Verification] TCT: mediacontroller and deprecated API 100% pass. New features tested in chrome console. Signed-off-by: Michal Michalski Change-Id: If2230979c33f253fbd80171937ac64a8d90d4215 --- diff --git a/src/mediacontroller/mediacontroller_api.js b/src/mediacontroller/mediacontroller_api.js index 80c1a891..65abb6ed 100755 --- a/src/mediacontroller/mediacontroller_api.js +++ b/src/mediacontroller/mediacontroller_api.js @@ -2862,23 +2862,64 @@ function MediaControllerClientInfo(data) { }); } +MediaControllerClientInfo.prototype.sendEvent = function(event, data, callback) { + var args = validator_.validateArgs(arguments, [ + { name: 'eventName', type: types_.STRING }, + { name: 'eventData', type: types_.DICTIONARY, nullable: true }, + { name: 'callback', type: types_.FUNCTION } + ]); + + var replyCallback = function(result, watchId) { + if ( + EventReplyListenerManager.listenerIdToRequestId[watchId] != result.requestId + ) { + return; + } + delete EventReplyListenerManager.listenerIdToRequestId[watchId]; + args.callback(result.resultCode, result.data); + }; + + var nativeData = { + eventName: args.eventName, + eventData: args.eventData === null ? null : new tizen.Bundle(args.eventData), + clientName: this.name, + replyListener: EventReplyListenerManager.name + }; + + var result = native_.callSync('MediaControllerClientInfo_sendEvent', nativeData); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + var replyListenerId = EventReplyListenerManager.addListener(replyCallback); + EventReplyListenerManager.listenerIdToRequestId[replyListenerId] = result.requestId; +}; + function MediaControllerClient() {} var EventReceivedCallback = function(msg, listener) { var result = listener(msg.serverName, msg.eventName, msg.eventData); - if (type_.isUndefined(result)) { - result = null; + if (!(result instanceof RequestReply)) { + result = new RequestReply( + xwalk.utils.type.isNullOrUndefined(result) ? null : result, + 0 + ); } + var nativeData = { result: result.data, - resultCode: result.resultCode, - serverName: msg.serverName, + resultCode: result.code, + serverName: msg.serverName , requestId: msg.requestId }; - //var nativeResult = native_.callSync('MediaControllerClient_sendEventReply', nativeData); - //if (native_.isFailure(nativeResult)) { - // throw native_.getErrorObject(nativeResult); - //} + + var nativeResult = native_.callSync( + 'MediaControllerClient_sendEventReply', + nativeData + ); + if (native_.isFailure(nativeResult)) { + throw native_.getErrorObject(nativeResult); + } }; MediaControllerClient.prototype.setCustomEventListener = function(listener) { diff --git a/src/mediacontroller/mediacontroller_client.cc b/src/mediacontroller/mediacontroller_client.cc index e236163d..66c63d15 100644 --- a/src/mediacontroller/mediacontroller_client.cc +++ b/src/mediacontroller/mediacontroller_client.cc @@ -37,7 +37,8 @@ using common::tools::ReportError; using common::tools::ReportSuccess; using common::BundleJsonIterator; -MediaControllerClient::MediaControllerClient() : handle_(nullptr), subscribed_servers{} { +MediaControllerClient::MediaControllerClient() + : handle_(nullptr), custom_event_listener_(nullptr), subscribed_servers{} { ScopeLogger(); } @@ -113,11 +114,13 @@ PlatformResult MediaControllerClient::Init() { PlatformResult MediaControllerClient::SetCustomEventListener(const JsonCallback& callback) { ScopeLogger(); - int ret = mc_client_set_custom_event_received_cb(handle_, OnEventReceived, this); - if (MEDIA_CONTROLLER_ERROR_NONE != ret) { - return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to set custom event listener", - ("mc_client_set_custom_event_received_cb() error: %d, message: %s", - ret, get_error_message(ret))); + if (custom_event_listener_ == nullptr) { + int ret = mc_client_set_custom_event_received_cb(handle_, OnEventReceived, this); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to set custom event listener", + ("mc_client_set_custom_event_received_cb() error: %d, message: %s", + ret, get_error_message(ret))); + } } custom_event_listener_ = callback; return PlatformResult(ErrorCode::NO_ERROR); @@ -135,6 +138,36 @@ PlatformResult MediaControllerClient::UnsetCustomEventListener() { return PlatformResult(ErrorCode::NO_ERROR); } +PlatformResult MediaControllerClient::SendEventReply(const char* server_name, + const picojson::value& data, int result_code, + const char* request_id) { + ScopeLogger(); + + bundle* data_bundle = bundle_create(); + if (!data_bundle) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "data_bundle is a nullptr", + ("bundle_create() returned a nullptr")); + } + SCOPE_EXIT { + free(data_bundle); + }; + + PlatformResult result = common::JsonToBundle(data, &data_bundle); + if (!result) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Converting json to bundle failed.", + ("JsonToBundle() failed with error: %s", result.message().c_str())); + } + + int ret = mc_client_send_event_reply(handle_, server_name, request_id, result_code, data_bundle); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult( + ErrorCode::UNKNOWN_ERR, "Failed to send event reply", + ("mc_client_send_event_reply() error: %d, message: %s", ret, get_error_message(ret))); + } + + return PlatformResult(ErrorCode::NO_ERROR); +} + PlatformResult MediaControllerClient::FindServers(picojson::array* servers) { ScopeLogger(); int ret; @@ -1684,12 +1717,16 @@ void MediaControllerClient::OnEventReceived(const char* server_name, const char* auto args = picojson::value(picojson::object()); auto& args_obj = args.get(); - picojson::array array; - bundle_foreach(data, BundleJsonIterator, &array); + picojson::value data_json; + PlatformResult result = common::BundleToJson(data, &data_json); + if (!result) { + LoggerE("BundleToJson() failed."); + return; + } args_obj[kServerName] = picojson::value(std::string(server_name)); args_obj[kEventName] = picojson::value(std::string(event_name)); - args_obj[kEventData] = picojson::value(array); + args_obj[kEventData] = data_json; args_obj[kRequestId] = picojson::value(std::string(request_id)); if (nullptr != client->custom_event_listener_) { diff --git a/src/mediacontroller/mediacontroller_client.h b/src/mediacontroller/mediacontroller_client.h index 385bd2b9..5b0aed26 100644 --- a/src/mediacontroller/mediacontroller_client.h +++ b/src/mediacontroller/mediacontroller_client.h @@ -108,6 +108,9 @@ class MediaControllerClient { common::PlatformResult SetCustomEventListener(const JsonCallback& callback); common::PlatformResult UnsetCustomEventListener(); + common::PlatformResult SendEventReply(const char* server_name, const picojson::value& data, + int result_code, const char* request_id); + private: mc_client_h handle_; diff --git a/src/mediacontroller/mediacontroller_instance.cc b/src/mediacontroller/mediacontroller_instance.cc index b76061c5..35839b2a 100644 --- a/src/mediacontroller/mediacontroller_instance.cc +++ b/src/mediacontroller/mediacontroller_instance.cc @@ -92,6 +92,9 @@ MediaControllerInstance::MediaControllerInstance() { REGISTER_SYNC("MediaControllerServer_setSimpleAbility", MediaControllerServerSetSimpleAbility); REGISTER_SYNC("MediaControllerServer_getAllClientsInfo", MediaControllerServerGetAllClientsInfo); + // client info + REGISTER_SYNC("MediaControllerClientInfo_sendEvent", MediaControllerClientInfoSendEvent); + // client REGISTER_SYNC("MediaControllerManager_getClient", MediaControllerManagerGetClient); REGISTER_ASYNC("MediaControllerClient_findServers", MediaControllerClientFindServers); @@ -111,6 +114,7 @@ MediaControllerInstance::MediaControllerInstance() { MediaControllerClientSetCustomEventListener); REGISTER_SYNC("MediaControllerClient_unsetCustomEventListener", MediaControllerClientUnsetCustomEventListener); + REGISTER_SYNC("MediaControllerClient_sendEventReply", MediaControllerClientSendEventReply); // server_info REGISTER_SYNC("MediaControllerServerInfo_sendPlaybackState", @@ -890,6 +894,45 @@ void MediaControllerInstance::MediaControllerServerGetAllClientsInfo(const picoj ReportSuccess(picojson::value(clientsInfo), out); } +void MediaControllerInstance::MediaControllerClientInfoSendEvent(const picojson::value& args, + picojson::object& out) { + ScopeLogger(); + if (!server_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occured."), &out, + ("Failed: server_")); + return; + } + + CHECK_ARGS(args, kEventName, std::string, out); + CHECK_EXIST(args, kEventData, out); + CHECK_ARGS(args, kClientName, std::string, out); + CHECK_ARGS(args, kReplyListener, std::string, out); + + JsonCallback reply_cb = [this, args](picojson::value* reply) -> void { + picojson::object& reply_obj = reply->get(); + reply_obj[kListenerId] = args.get(kReplyListener); + Instance::PostMessage(this, reply->serialize().c_str()); + }; + + char* request_id = nullptr; + SCOPE_EXIT { + free(request_id); + }; + + auto& args_obj = args.get(); + PlatformResult result = server_->SendEvent(args_obj.at(kEventName).get().c_str(), + args_obj.at(kEventData), + args_obj.at(kClientName).get().c_str(), + reply_cb, &request_id); + + if (result) { + out[kRequestId] = picojson::value(std::string(request_id)); + ReportSuccess(out); + } else { + LogAndReportError(result, &out, ("Failed to send event.")); + } +} + void MediaControllerInstance::MediaControllerManagerGetClient(const picojson::value& args, picojson::object& out) { ScopeLogger(); @@ -911,6 +954,33 @@ void MediaControllerInstance::MediaControllerManagerGetClient(const picojson::va ReportSuccess(out); } +void MediaControllerInstance::MediaControllerClientSendEventReply(const picojson::value& args, + picojson::object& out) { + ScopeLogger(); + if (!client_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occured."), &out, + ("Failed: client_")); + return; + } + + CHECK_ARGS(args, kServerName, std::string, out); + CHECK_EXIST(args, kResult, out); + CHECK_ARGS(args, kRequestId, std::string, out); + CHECK_ARGS(args, kResultCode, double, out); + + auto result = + client_->SendEventReply(args.get(kServerName).get().c_str(), args.get(kResult), + static_cast(args.get(kResultCode).get()), + args.get(kRequestId).get().c_str()); + + if (!result) { + LogAndReportError(result, &out); + return; + } + + ReportSuccess(out); +} + void MediaControllerInstance::MediaControllerClientSetCustomEventListener( const picojson::value& args, picojson::object& out) { ScopeLogger(); diff --git a/src/mediacontroller/mediacontroller_instance.h b/src/mediacontroller/mediacontroller_instance.h index cac54901..b73765a9 100644 --- a/src/mediacontroller/mediacontroller_instance.h +++ b/src/mediacontroller/mediacontroller_instance.h @@ -74,6 +74,9 @@ class MediaControllerInstance : public common::ParsedInstance { void MediaControllerServerSetSimpleAbility(const picojson::value& args, picojson::object& out); void MediaControllerServerGetAllClientsInfo(const picojson::value& args, picojson::object& out); + // client info + void MediaControllerClientInfoSendEvent(const picojson::value& args, picojson::object& out); + // client void MediaControllerManagerGetClient(const picojson::value& args, picojson::object& out); void MediaControllerClientFindServers(const picojson::value& args, picojson::object& out); @@ -95,6 +98,7 @@ class MediaControllerInstance : public common::ParsedInstance { picojson::object& out); void MediaControllerClientUnsetCustomEventListener(const picojson::value& args, picojson::object& out); + void MediaControllerClientSendEventReply(const picojson::value& args, picojson::object& out); // serverInfo void MediaControllerServerInfoSendPlaybackState(const picojson::value& args, diff --git a/src/mediacontroller/mediacontroller_server.cc b/src/mediacontroller/mediacontroller_server.cc index 8258decb..28c21ee1 100644 --- a/src/mediacontroller/mediacontroller_server.cc +++ b/src/mediacontroller/mediacontroller_server.cc @@ -80,6 +80,11 @@ MediaControllerServer::~MediaControllerServer() { LoggerE("Failed to unset display rotation listener"); } + int ret = mc_server_unset_event_reply_received_cb(handle_); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + LoggerE("Failed to unset event reply received callback"); + } + for (auto const& v : playlist_handle_map_) { if (MEDIA_CONTROLLER_ERROR_NONE != mc_playlist_destroy(v.second)) { LoggerE("Unable to destroy playlist %s", v.first.c_str()); @@ -101,6 +106,14 @@ PlatformResult MediaControllerServer::Init() { ("mc_server_create() error: %d, message: %s", ret, get_error_message(ret))); } + ret = mc_server_set_event_reply_received_cb(handle_, OnEventReply, this); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, + "Unable to register event reply received callback", + ("mc_server_set_event_reply_received_cb() error: %d, message: %s", + ret, get_error_message(ret))); + } + return PlatformResult(ErrorCode::NO_ERROR); } @@ -1050,6 +1063,29 @@ void MediaControllerServer::OnPlaybackPositionCommand(const char* client_name, server->change_request_playback_info_listener_(&data); } +void MediaControllerServer::OnEventReply(const char* client_name, const char* request_id, + int result_code, bundle* data, void* user_data) { + ScopeLogger(); + auto server = static_cast(user_data); + + picojson::value json_data = picojson::value(picojson::object()); + auto& json_data_obj = json_data.get(); + + json_data_obj[kResultCode] = picojson::value(static_cast(result_code)); + json_data_obj[kClientName] = picojson::value(std::string(client_name)); + json_data_obj[kRequestId] = picojson::value(std::string(request_id)); + + picojson::value data_json; + auto result = common::BundleToJson(data, &data_json); + if (!result) { + LoggerE("BundleToJson() failed in OnEventReply."); + return; + } + json_data_obj[kData] = data_json; + + server->event_reply_callback_(&json_data); +} + void MediaControllerServer::OnShuffleModeCommand(const char* client_name, const char* request_id, mc_shuffle_mode_e mode, void* user_data) { ScopeLogger(); @@ -1430,5 +1466,40 @@ PlatformResult MediaControllerServer::GetAllClientsInfo(picojson::array* clients return PlatformResult(ErrorCode::NO_ERROR); } +PlatformResult MediaControllerServer::SendEvent(const char* event_name, + const picojson::value& event_data, + const char* client_name, + const JsonCallback& reply_cb, char** request_id) { + ScopeLogger(); + + bundle* event_data_bundle = bundle_create(); + SCOPE_EXIT { + free(event_data_bundle); + }; + + PlatformResult result = common::JsonToBundle(event_data, &event_data_bundle); + if (!result) { + return LogAndCreateResult(result.error_code(), "Event data to bundle conversion failed", + ("JsonToBundle() failed with error: %s", result.message().c_str())); + } + + if (!event_data_bundle) { + LoggerD("data is null"); + } + + int ret = + mc_server_send_custom_event(handle_, client_name, event_name, event_data_bundle, request_id); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult( + ErrorCode::UNKNOWN_ERR, "sending custom event failed", + ("mc_server_send_custom_event() returned error code: %d. Error message: %s", ret, + get_error_message(ret))); + } + + event_reply_callback_ = reply_cb; + + return PlatformResult(ErrorCode::NO_ERROR); +} + } // namespace mediacontroller } // namespace extension diff --git a/src/mediacontroller/mediacontroller_server.h b/src/mediacontroller/mediacontroller_server.h index 42eae205..8cd88c4c 100644 --- a/src/mediacontroller/mediacontroller_server.h +++ b/src/mediacontroller/mediacontroller_server.h @@ -76,30 +76,32 @@ class MediaControllerServer { common::PlatformResult GetAllClientsInfo(picojson::array* clientsInfo); - // subtitles common::PlatformResult UpdateSubtitlesEnabled(bool enabled); common::PlatformResult SetSubtitlesChangeRequestListener(const JsonCallback& callback); common::PlatformResult UnsetSubtitlesChangeRequestListener(); - // mode360 common::PlatformResult UpdateMode360Enabled(bool enabled); common::PlatformResult SetMode360ChangeRequestListener(const JsonCallback& callback); common::PlatformResult UnsetMode360ChangeRequestListener(); - // displayMode common::PlatformResult UpdateDisplayModeType(const std::string& type); common::PlatformResult SetDisplayModeChangeRequestListener(const JsonCallback& callback); common::PlatformResult UnsetDisplayModeChangeRequestListener(); - // displayRotation common::PlatformResult UpdateDisplayRotation(const std::string& display_rotation); common::PlatformResult SetDisplayRotationChangeRequestListener(const JsonCallback& callback); common::PlatformResult UnsetDisplayRotationChangeRequestListener(); + common::PlatformResult SendEvent(const char* event_name, const picojson::value& event_data, + const char* client_name, const JsonCallback& reply_cb, + char** request_id); + private: mc_server_h handle_; JsonCallback change_request_playback_info_listener_; + JsonCallback event_reply_callback_; + mc_playback_states_e playback_state_; unsigned long long position_; mc_content_age_rating_e age_rating_; @@ -126,7 +128,8 @@ class MediaControllerServer { const char* playlist_name, const char* index, mc_playback_action_e action, unsigned long long position, void* user_data); - + static void OnEventReply(const char* client_name, const char* request_id, + int result_code, bundle* data, void* user_data); static void OnSearchRequestReceived(const char* client_name, const char* request_id, mc_search_h request, void* user_data); static void OnCommandReceived(const char* client_name, const char* request_id, diff --git a/src/mediacontroller/mediacontroller_utils.cc b/src/mediacontroller/mediacontroller_utils.cc index 1404b224..ef523427 100644 --- a/src/mediacontroller/mediacontroller_utils.cc +++ b/src/mediacontroller/mediacontroller_utils.cc @@ -71,12 +71,14 @@ const char* kPosition = "position"; const char* kRating = "rating"; const char* kRepeatMode = "repeatMode"; const char* kReply = "reply"; +const char* kReplyListener = "replyListener"; const char* kRequest = "request"; const char* kRequestId = "requestId"; const char* kResolution = "resolution"; const char* kResolutionHeight = "resolutionHeight"; const char* kResolutionWidth = "resolutionWidth"; const char* kResult = "result"; +const char* kResultCode = "resultCode"; const char* kSeason = "season"; const char* kSeasonNumber = "seasonNumber"; const char* kSeasonTitle = "seasonTitle"; diff --git a/src/mediacontroller/mediacontroller_utils.h b/src/mediacontroller/mediacontroller_utils.h index 2bd30625..8b56e4b9 100644 --- a/src/mediacontroller/mediacontroller_utils.h +++ b/src/mediacontroller/mediacontroller_utils.h @@ -69,9 +69,11 @@ extern const char* kPosition; extern const char* kRating; extern const char* kRepeatMode; extern const char* kReply; +extern const char* kReplyListener; extern const char* kRequest; extern const char* kRequestId; extern const char* kResult; +extern const char* kResultCode; extern const char* kServerName; extern const char* kShuffleMode; extern const char* kState; diff --git a/src/utils/utils_api.js b/src/utils/utils_api.js index 699ae6f2..03c44dd0 100644 --- a/src/utils/utils_api.js +++ b/src/utils/utils_api.js @@ -57,7 +57,7 @@ var CommonListenerManager = function(nativeMgr, managerName, onIdNotFound) { CommonListenerManager.prototype.onListenerCalled = function(msg) { for (var watchId in this.listeners) { if (this.listeners.hasOwnProperty(watchId)) { - this.listeners[watchId](msg); + this.listeners[watchId](msg, watchId); } } };