[utils][mediacontroller] SendEvent() method implementation. 72/215472/5
authorMichal Michalski <m.michalski2@partner.samsung.com>
Tue, 8 Oct 2019 15:10:04 +0000 (17:10 +0200)
committerPiotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/삼성전자 <p.kosko@samsung.com>
Wed, 9 Oct 2019 05:31:38 +0000 (07:31 +0200)
[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 <m.michalski2@partner.samsung.com>
Change-Id: If2230979c33f253fbd80171937ac64a8d90d4215

src/mediacontroller/mediacontroller_api.js
src/mediacontroller/mediacontroller_client.cc
src/mediacontroller/mediacontroller_client.h
src/mediacontroller/mediacontroller_instance.cc
src/mediacontroller/mediacontroller_instance.h
src/mediacontroller/mediacontroller_server.cc
src/mediacontroller/mediacontroller_server.h
src/mediacontroller/mediacontroller_utils.cc
src/mediacontroller/mediacontroller_utils.h
src/utils/utils_api.js

index 80c1a891bb8cb05cbe25fd066ac5582640726d17..65abb6edd18f725cb02f51c44f32d5b2f8a034c8 100755 (executable)
@@ -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) {
index e236163d569daee4adb1b6bc3ffe3d3bb7840ca6..66c63d15d5bc6000a6822c7e68d6d9e2d9ad6009 100644 (file)
@@ -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::object>();
 
-  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_) {
index 385bd2b948e3ed6f09bf1278858c517c47c2663c..5b0aed26a999072d79b2126c085d585cf2f7cc8a 100644 (file)
@@ -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_;
 
index b76061c537ca9ec22bb373a7b2898e66d7f68363..35839b2adbec0e334a39156241931971e0543ddc 100644 (file)
@@ -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<picojson::object>();
+    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<picojson::object>();
+  PlatformResult result = server_->SendEvent(args_obj.at(kEventName).get<std::string>().c_str(),
+                                             args_obj.at(kEventData),
+                                             args_obj.at(kClientName).get<std::string>().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<std::string>().c_str(), args.get(kResult),
+                              static_cast<int>(args.get(kResultCode).get<double>()),
+                              args.get(kRequestId).get<std::string>().c_str());
+
+  if (!result) {
+    LogAndReportError(result, &out);
+    return;
+  }
+
+  ReportSuccess(out);
+}
+
 void MediaControllerInstance::MediaControllerClientSetCustomEventListener(
     const picojson::value& args, picojson::object& out) {
   ScopeLogger();
index cac549017670fd76d0794999e4e65bea4b90fcdb..b73765a96cc03e918754642c5087ed94892cf9c8 100644 (file)
@@ -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,
index 8258decbfba9f48abfdee27125314b0fc950883e..28c21ee1595fb0ca7b35fff35f1c042fad21793e 100644 (file)
@@ -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<MediaControllerServer*>(user_data);
+
+  picojson::value json_data = picojson::value(picojson::object());
+  auto& json_data_obj = json_data.get<picojson::object>();
+
+  json_data_obj[kResultCode] = picojson::value(static_cast<double>(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
index 42eae20577c1b5315c662f698d050fcd8ec8928b..8cd88c4c91594befc8870055cefd667e8c3ad097 100644 (file)
@@ -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,
index 1404b224729865d859df557a7e9a19dc7cf4f47a..ef52342798b43890eaebbb0369b227f05bae65b0 100644 (file)
@@ -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";
index 2bd30625384dae01c77ac298eb554ca2549b1097..8b56e4b9276f876b512a09a98d23246070f5de32 100644 (file)
@@ -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;
index 699ae6f2be6b77ab0868f536c212cb189bcede9e..03c44dd046cc064b4590b4cf93aefea73bf8ef30 100644 (file)
@@ -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);
         }
     }
 };