[MediaController] Playback state implementation
authorRafal Galka <r.galka@samsung.com>
Wed, 22 Apr 2015 07:06:44 +0000 (09:06 +0200)
committerRafal Galka <r.galka@samsung.com>
Tue, 28 Apr 2015 10:24:36 +0000 (19:24 +0900)
- (client) send playback state
- (server) onplaybackstaterequest listener

Change-Id: I2c9110d3ec23932b494e0f186c8ccc0e8cab0946
Signed-off-by: Rafal Galka <r.galka@samsung.com>
src/mediacontroller/mediacontroller_api.js
src/mediacontroller/mediacontroller_client.cc
src/mediacontroller/mediacontroller_client.h
src/mediacontroller/mediacontroller_instance.cc
src/mediacontroller/mediacontroller_server.cc
src/mediacontroller/mediacontroller_server.h

index 9d296db..1c1b774 100644 (file)
@@ -410,12 +410,21 @@ MediaControllerServer.prototype.updateMetadata = function(metadata) {
 };
 
 MediaControllerServer.prototype.addChangeRequestPlaybackInfoListener = function(listener) {
-  var args = validator_.validateArgs(arguments, [
-    {name: 'listener', type: types_.LISTENER, values: ['onplaybackstaterequest', 'onplaybackpositionrequest', 'onshufflemoderequest', 'onrepeatmoderequest']}
-  ]);
+  var args = validator_.validateArgs(arguments, [{
+    name: 'listener',
+    type: types_.LISTENER,
+    values: [
+      'onplaybackstaterequest',
+      'onplaybackpositionrequest',
+      'onshufflemoderequest',
+      'onrepeatmoderequest'
+    ]
+  }]);
 
   if (type_.isEmptyObject(ServerPlaybackInfoListener.listeners)) {
-    var result = native_.callSync('MediaControllerServer_addChangeRequestPlaybackInfoListener');
+    var result = native_.callSync('MediaControllerServer_addChangeRequestPlaybackInfoListener', {
+      listenerId: ServerPlaybackInfoListener.listenerName
+    });
     if (native_.isFailure(result)) {
       throw native_.getErrorObject(result);
     }
@@ -442,7 +451,9 @@ MediaControllerServer.prototype.addCommandListener = function(listener) {
   ]);
 
   if (type_.isEmptyObject(ServerCommandListener.listeners)) {
-    var result = native_.callSync('MediaControllerServer_addCommandListener');
+    var result = native_.callSync('MediaControllerServer_addCommandListener', {
+      listenerId: ServerCommandListener.listenerName
+    });
     if (native_.isFailure(result)) {
       throw native_.getErrorObject(result);
     }
@@ -544,6 +555,7 @@ MediaControllerServerInfo.prototype.sendPlaybackState = function(state, successC
   ]);
 
   var data = {
+    name: this.name,
     state: args.state
   };
 
@@ -660,7 +672,9 @@ MediaControllerServerInfo.prototype.addServerStatusChangeListener = function(lis
   ]);
 
   if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) {
-    var result = native_.callSync('MediaControllerServerInfo_addServerStatusChangeListener');
+    var result = native_.callSync('MediaControllerServerInfo_addServerStatusChangeListener', {
+      listenerId: ServerInfoStatusListener.listenerName
+    });
     if (native_.isFailure(result)) {
       throw native_.getErrorObject(result);
     }
index 282dc67..2fd88b4 100644 (file)
@@ -412,5 +412,31 @@ void MediaControllerClient::OnMetadataUpdate(const char* server_name,
   client->playback_info_listener_(&data);
 }
 
+PlatformResult MediaControllerClient::SendPlaybackState(
+    const std::string& server_name,
+    const std::string& state) {
+  LOGGER(DEBUG) << "entered";
+
+  int ret;
+
+  int state_e;
+  PlatformResult result = Types::StringToPlatformEnum(
+      Types::kMediaControllerPlaybackState, state, &state_e);
+  if (!result) {
+    return result;
+  }
+
+  ret = mc_client_send_playback_state_command(
+      handle_, server_name.c_str(), static_cast<mc_playback_states_e>(state_e));
+  if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+    LOGGER(ERROR) << "mc_client_send_playback_state_command failed, error: "
+        << ret;
+    return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                          "Error sending playback state");
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 } // namespace mediacontroller
 } // namespace extension
index f904344..eb36266 100644 (file)
@@ -28,6 +28,9 @@ class MediaControllerClient {
   common::PlatformResult GetMetadata(const std::string& server_name,
                                          picojson::object* metadata);
 
+  common::PlatformResult SendPlaybackState(const std::string& server_name,
+                                           const std::string& state);
+
   common::PlatformResult SetPlaybackInfoListener(JsonCallback callback);
  private:
   mc_client_h handle_;
index 1cb869c..f171f09 100644 (file)
@@ -237,28 +237,47 @@ void MediaControllerInstance::MediaControllerServerUpdateMetadata(
 void MediaControllerInstance::MediaControllerServerAddChangeRequestPlaybackInfoListener(
     const picojson::value& args,
     picojson::object& out) {
+  LOGGER(DEBUG) << "entered";
 
-  // implement it
+  if (!server_) {
+    ReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR,
+                               "Server not initialized."), &out);
+    return;
+  }
 
-  // if success
-  // ReportSuccess(out);
-  // if error
-  // ReportError(out);
+  CHECK_EXIST(args, "listenerId", out)
+
+  JsonCallback callback = [this, args](picojson::value* data) -> void {
+    LOGGER(DEBUG) << "entered";
+
+    if (nullptr == data) {
+      LOGGER(ERROR) << "No data passed to json callback";
+      return;
+    }
+
+    picojson::object& request_o = data->get<picojson::object>();
+    request_o["listenerId"] = args.get("listenerId");
+
+    PostMessage(data->serialize().c_str());
+  };
+
+  server_->SetChangeRequestPlaybackInfoListener(callback);
+
+  ReportSuccess(out);
 }
 
 void MediaControllerInstance::MediaControllerServerRemoveChangeRequestPlaybackInfoListener(
     const picojson::value& args,
     picojson::object& out) {
-  CHECK_EXIST(args, "watchId", out)
-
-  double watchId = args.get("watchId").get<double>();
+  LOGGER(DEBUG) << "entered";
 
-  // implement it
+  if (!server_) {
+    ReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR,
+                               "Server not initialized."), &out);
+    return;
+  }
 
-  // if success
-  // ReportSuccess(out);
-  // if error
-  // ReportError(out);
+  server_->SetChangeRequestPlaybackInfoListener(nullptr);
 }
 
 void MediaControllerInstance::MediaControllerServerAddCommandListener(
@@ -393,18 +412,40 @@ void MediaControllerInstance::MediaControllerClientGetPlaybackInfo(
 void MediaControllerInstance::MediaControllerServerInfoSendPlaybackState(
     const picojson::value& args,
     picojson::object& out) {
+
+  if (!client_) {
+    ReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR,
+                               "Client not initialized."), &out);
+    return;
+  }
+
   CHECK_EXIST(args, "callbackId", out)
+  CHECK_EXIST(args, "name", out)
+  CHECK_EXIST(args, "state", out)
 
-  int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+  auto send = [this, args]() -> void {
+    LOGGER(DEBUG) << "entered";
 
-  // implement it
+    picojson::value response = picojson::value(picojson::object());
+    picojson::object& response_obj = response.get<picojson::object>();
+    response_obj["callbackId"] = args.get("callbackId");
 
-  // call ReplyAsync in later (Asynchronously)
+    PlatformResult result = client_->SendPlaybackState(
+        args.get("name").get<std::string>(),
+        args.get("state").get<std::string>());
 
-  // if success
-  // ReportSuccess(out);
-  // if error
-  // ReportError(out);
+    if (result) {
+      ReportSuccess(response_obj);
+    } else {
+      ReportError(result, &response_obj);
+    }
+
+    PostMessage(response.serialize().c_str());
+  };
+
+  TaskQueue::GetInstance().Async(send);
+
+  ReportSuccess(out);
 }
 
 void MediaControllerInstance::MediaControllerServerInfoSendPlaybackPosition(
index 5ecd7aa..23c409c 100644 (file)
@@ -150,5 +150,67 @@ common::PlatformResult MediaControllerServer::SetMetadata(
   return result;
 }
 
+PlatformResult MediaControllerServer::SetChangeRequestPlaybackInfoListener(
+    JsonCallback callback) {
+
+  if (callback && change_request_playback_info_listener_) {
+    LOGGER(ERROR) << "Listener already registered";
+    return PlatformResult(ErrorCode::INVALID_STATE_ERR,
+                          "Listener already registered");
+  }
+
+  change_request_playback_info_listener_ = callback;
+
+  int ret;
+  if (callback) { // set platform callbacks
+    ret = mc_server_set_playback_state_command_received_cb(
+        handle_, OnPlaybackStateCommand, this);
+    if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+      LOGGER(ERROR) << "Unable to set playback state command listener, error: " << ret;
+      return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                            "Unable to set playback state command listener");
+    }
+  } else { // unset platform callbacks
+    ret = mc_server_unset_playback_state_command_received_cb(handle_);
+    if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+      LOGGER(ERROR) << "Unable to unset playback state command listener, error: " << ret;
+      return PlatformResult(ErrorCode::UNKNOWN_ERR,
+                            "Unable to unset playback state command listener");
+    }
+  }
+
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+void MediaControllerServer::OnPlaybackStateCommand(const char* client_name,
+                                                   mc_playback_states_e state_e,
+                                                   void *user_data) {
+  LOGGER(DEBUG) << "entered";
+
+  MediaControllerServer* server = static_cast<MediaControllerServer*>(user_data);
+
+  if (!server->change_request_playback_info_listener_) {
+    LOGGER(DEBUG) << "No change request playback info listener registered, skipping";
+    return;
+  }
+
+  std::string state;
+  PlatformResult result = Types::PlatformEnumToString(
+      Types::kMediaControllerPlaybackState,
+      static_cast<int>(state_e), &state);
+  if (!result) {
+    LOGGER(ERROR) << "PlatformEnumToString failed, error: " << result.message();
+    return;
+  }
+
+  picojson::value data = picojson::value(picojson::object());
+  picojson::object& data_o = data.get<picojson::object>();
+
+  data_o["action"] = picojson::value(std::string("onplaybackstaterequest"));
+  data_o["state"] = picojson::value(state);
+
+  server->change_request_playback_info_listener_(&data);
+}
+
 } // namespace mediacontroller
 } // namespace extension
index 8ac75bc..427181e 100644 (file)
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "common/platform_result.h"
+#include "mediacontroller/mediacontroller_types.h"
 
 namespace extension {
 namespace mediacontroller {
@@ -25,8 +26,16 @@ class MediaControllerServer {
   common::PlatformResult SetRepeatMode(bool mode);
   common::PlatformResult SetMetadata(const picojson::object& metadata);
 
+  common::PlatformResult SetChangeRequestPlaybackInfoListener(
+      JsonCallback callback);
+
  private:
   mc_server_h handle_;
+  JsonCallback change_request_playback_info_listener_;
+
+  static void OnPlaybackStateCommand(const char* client_name,
+                                     mc_playback_states_e state_e,
+                                     void *user_data);
 };
 
 } // namespace mediacontroller