[6.0][mediacontroller] add methods to MediaControllerServerPlaybackInfo 14/217014/8
authorDawid Juszczak <d.juszczak@samsung.com>
Mon, 4 Nov 2019 16:11:19 +0000 (17:11 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Thu, 5 Dec 2019 16:00:10 +0000 (16:00 +0000)
[acr]
http://suprem.sec.samsung.net/jira/browse/TWDAPI-246

[description]
>> refactor_03 <<
add methods to serverInfoPlaybackInfo interface:
+ sendPlaybackAction
+ sendPlaybackPosition
+ sendShuffleMode
+ sendRepeatState
+ addPlaybackInfoChangeListener
+ removePlaybackInfoChangeListener

[verification]
tested manually in chrome console
tct-mediacontroller-tizen-tests fails with 2 TC:
- MediaControllerServer_iconURI_attribute.html <- has to be modified,
  because attribute iconURI is no longer readonly
- MediaControllerServerInfo_iconURI_attribute.html <- has to be modified,
  because attribute iconURI is no longer readonly

Change-Id: I3b24e1e3d6bfee1ced8d24962a790ae9e71b445a
Signed-off-by: Dawid Juszczak <d.juszczak@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_instance.h
src/mediacontroller/mediacontroller_server.cc
src/mediacontroller/mediacontroller_utils.cc
src/mediacontroller/mediacontroller_utils.h
src/utils/utils_api.js

index 5dc8c41..f26d6e1 100755 (executable)
@@ -168,6 +168,7 @@ var ServerPlaybackInfoListener = new ListenerManager(
     native_,
     '_ServerPlaybackInfoListener',
     function(msg, listener) {
+        var reply = null;
         if (msg.action === 'onplaybackstaterequest') {
             utils_.printDeprecationWarningFor(
                 'onplaybackstaterequest',
@@ -176,13 +177,25 @@ var ServerPlaybackInfoListener = new ListenerManager(
             native_.callIfPossible(listener[msg.action], msg.state, msg.clientName);
         }
         if (msg.action === 'onplaybackactionrequest') {
-            native_.callIfPossible(listener[msg.action], msg.state, msg.clientName);
+            reply = native_.callIfPossibleAndReturn(
+                listener[msg.action],
+                msg.state,
+                msg.clientName
+            );
         }
         if (msg.action === 'onplaybackpositionrequest') {
-            native_.callIfPossible(listener[msg.action], msg.position, msg.clientName);
+            reply = native_.callIfPossibleAndReturn(
+                listener[msg.action],
+                msg.position,
+                msg.clientName
+            );
         }
         if (msg.action === 'onshufflemoderequest') {
-            native_.callIfPossible(listener[msg.action], msg.mode, msg.clientName);
+            reply = native_.callIfPossibleAndReturn(
+                listener[msg.action],
+                msg.mode,
+                msg.clientName
+            );
         }
         if (msg.action === 'onrepeatmoderequest') {
             utils_.printDeprecationWarningFor(
@@ -192,10 +205,14 @@ var ServerPlaybackInfoListener = new ListenerManager(
             native_.callIfPossible(listener[msg.action], msg.mode, msg.clientName);
         }
         if (msg.action === 'onrepeatstaterequest') {
-            native_.callIfPossible(listener[msg.action], msg.state, msg.clientName);
+            reply = native_.callIfPossibleAndReturn(
+                listener[msg.action],
+                msg.state,
+                msg.clientName
+            );
         }
         if (msg.action === 'onplaybackitemrequest') {
-            native_.callIfPossible(
+            reply = native_.callIfPossibleAndReturn(
                 listener[msg.action],
                 msg.playlistName,
                 msg.index,
@@ -204,6 +221,25 @@ var ServerPlaybackInfoListener = new ListenerManager(
                 msg.clientName
             );
         }
+
+        if (!type_.isNullOrUndefined(reply)) {
+            if (!(reply instanceof RequestReply)) {
+                reply = new RequestReply(reply,0);
+            }
+
+            var nativeData = {
+                clientName: msg.clientName,
+                requestId: msg.requestId,
+                reply: reply
+            };
+            var result = native_.callSync(
+                'MediaControllerServerReplyCommand',
+                nativeData
+            );
+            if (native_.isFailure(result)) {
+                throw native_.getErrorObject(result);
+            }
+        }
     }
 );
 
@@ -3343,6 +3379,11 @@ MediaControllerServerInfo.prototype.sendPlaybackState = function(
     successCallback,
     errorCallback
 ) {
+    utils_.printDeprecationWarningFor(
+        'MediaControllerServerInfo.sendPlaybackState()',
+        'MediaControllerServerInfoPlaybackInfo.sendPlaybackAction()'
+    );
+
     var args = validator_.validateArgs(arguments, [
         {
             name: 'state',
@@ -3379,6 +3420,10 @@ MediaControllerServerInfo.prototype.sendPlaybackPosition = function(
     successCallback,
     errorCallback
 ) {
+    utils_.printDeprecationWarningFor(
+        'MediaControllerServerInfo.sendPlaybackPosition()',
+        'MediaControllerServerInfoPlaybackInfo.sendPlaybackPosition()'
+    );
     var args = validator_.validateArgs(arguments, [
         { name: 'position', type: types_.LONG_LONG },
         {
@@ -3404,7 +3449,7 @@ MediaControllerServerInfo.prototype.sendPlaybackPosition = function(
 
     var data = {
         position: args.position,
-        name: this.name
+        serverName: this.name
     };
 
     native_.call('MediaControllerServerInfoSendPlaybackPosition', data, callback);
@@ -3415,6 +3460,10 @@ MediaControllerServerInfo.prototype.sendShuffleMode = function(
     successCallback,
     errorCallback
 ) {
+    utils_.printDeprecationWarningFor(
+        'MediaControllerServerInfo.sendShuffleMode()',
+        'MediaControllerServerInfoPlaybackInfo.sendShuffleMode()'
+    );
     var args = validator_.validateArgs(arguments, [
         { name: 'mode', type: types_.BOOLEAN },
         {
@@ -3436,7 +3485,7 @@ MediaControllerServerInfo.prototype.sendShuffleMode = function(
 
     var data = {
         mode: args.mode,
-        name: this.name
+        serverName: this.name
     };
     native_.call('MediaControllerServerInfoSendShuffleMode', data, callback);
 };
@@ -3473,7 +3522,15 @@ MediaControllerServerInfo.prototype.sendRepeatMode = function(
     native_.call('MediaControllerServerInfoSendRepeatMode', data, callback);
 };
 
-MediaControllerServerInfo.prototype.sendRepeatState = function() {
+MediaControllerServerInfo.prototype.sendRepeatState = function(
+    state,
+    successCallback,
+    errorCallback
+) {
+    utils_.printDeprecationWarningFor(
+        'MediaControllerServerInfo.sendRepeatState()',
+        'MediaControllerServerInfoPlaybackInfo.sendRepeatState()'
+    );
     var args = validator_.validateArgs(arguments, [
         {
             name: 'state',
@@ -3499,7 +3556,7 @@ MediaControllerServerInfo.prototype.sendRepeatState = function() {
 
     var data = {
         state: args.state,
-        name: this.name
+        serverName: this.name
     };
     native_.call('MediaControllerServerInfoSendRepeatState', data, callback);
 };
@@ -3623,8 +3680,21 @@ MediaControllerServerInfo.prototype.removeServerStatusChangeListener = function(
 };
 
 MediaControllerServerInfo.prototype.addPlaybackInfoChangeListener = function(listener) {
+    utils_.printDeprecationWarningFor(
+        'MediaControllerServerInfo.addPlaybackInfoChangeListener()',
+        'MediaControllerServerInfoPlaybackInfo.addPlaybackInfoChangeListener()'
+    );
+    var args = [this.name].concat(Array.prototype.slice.call(arguments));
+    return addPlaybackInfoChangeListener.apply(this, args);
+};
+
+var addPlaybackInfoChangeListener = function(serverName, listener) {
     var args = validator_.validateArgs(arguments, [
         {
+            name: 'serverName',
+            type: types_.STRING
+        },
+        {
             name: 'listener',
             type: types_.LISTENER,
             values: [
@@ -3649,10 +3719,21 @@ MediaControllerServerInfo.prototype.addPlaybackInfoChangeListener = function(lis
         }
     }
 
-    return ServerInfoPlaybackInfoListener.addServerInfoListener(args.listener, this.name);
+    return ServerInfoPlaybackInfoListener.addServerInfoListener(
+        args.listener,
+        args.serverName
+    );
 };
 
 MediaControllerServerInfo.prototype.removePlaybackInfoChangeListener = function(watchId) {
+    utils_.printDeprecationWarningFor(
+        'MediaControllerServerInfo.removePlaybackInfoChangeListener()',
+        'MediaControllerServerInfoPlaybackInfo.removePlaybackInfoChangeListener()'
+    );
+    removePlaybackInfoChangeListener(watchId);
+};
+
+var removePlaybackInfoChangeListener = function(watchId) {
     var args = validator_.validateArgs(arguments, [
         { name: 'watchId', type: types_.LONG }
     ]);
@@ -4084,7 +4165,7 @@ MediaControllerServerPlaybackInfo.prototype.removeChangeRequestListener = functi
 };
 
 function MediaControllerServerInfoPlaybackInfo(serverName, data) {
-    var _serverName = serverName; // this variable will be used in the future
+    var _serverName = serverName;
 
     Object.defineProperties(this, {
         state: {
@@ -4133,8 +4214,116 @@ function MediaControllerServerInfoPlaybackInfo(serverName, data) {
             writable: false
         }
     });
+
+    this.sendPlaybackAction = function(action, replyCallback) {
+        sendRequestWithReply(
+            _serverName,
+            'action',
+            types_.ENUM,
+            Object.keys(MediaControllerPlaybackAction),
+            'MediaControllerServerInfoPlaybackInfoSendPlaybackAction',
+            action,
+            replyCallback
+        );
+    };
+
+    this.sendPlaybackPosition = function(position, replyCallback) {
+        sendRequestWithReply(
+            _serverName,
+            'position',
+            types_.LONG_LONG,
+            null,
+            'MediaControllerServerInfoPlaybackInfoSendPlaybackPosition',
+            position,
+            replyCallback
+        );
+    };
+
+    this.sendShuffleMode = function(mode, replyCallback) {
+        sendRequestWithReply(
+            _serverName,
+            'mode',
+            types_.BOOLEAN,
+            null,
+            'MediaControllerServerInfoPlaybackInfoSendShuffleMode',
+            mode,
+            replyCallback
+        );
+    };
+
+    this.sendRepeatState = function(state, replyCallback) {
+        sendRequestWithReply(
+            _serverName,
+            'state',
+            types_.ENUM,
+            Object.keys(MediaControllerRepeatState),
+            'MediaControllerServerInfoPlaybackInfoSendRepeatState',
+            state,
+            replyCallback
+        );
+    };
+
+    this.addPlaybackInfoChangeListener = function(listener) {
+        var args = [_serverName].concat(Array.prototype.slice.call(arguments));
+        return addPlaybackInfoChangeListener.apply(this, args);
+    };
+
+    this.removePlaybackInfoChangeListener = function(watchId) {
+        removePlaybackInfoChangeListener(watchId);
+    };
 }
 
+var sendRequestWithReply = function(
+    serverName,
+    attribName,
+    attribType,
+    attribValues,
+    callString,
+    attribVal,
+    replyCB
+) {
+    var toValidate = [attribVal];
+    if (undefined !== replyCB) {
+        toValidate.push(replyCB);
+    }
+
+    var args = validator_.validateArgs(toValidate, [
+        {
+            name: attribName,
+            type: attribType,
+            values: attribValues
+        },
+        {
+            name: 'replyCallback',
+            type: types_.FUNCTION,
+            optional: true,
+            nullable: true
+        }
+    ]);
+
+    var callback = function(result) {
+        native_.callIfPossible(
+            args.replyCallback,
+            native_.getResultObject(result).data,
+            native_.getResultObject(result).code
+        );
+    };
+
+    var nativeData = {
+        attribute: args[attribName],
+        serverName: serverName,
+        listenerId: ReplyCommandListener.listenerName
+    };
+
+    var result = native_.callSync(callString, nativeData);
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObject(result);
+    }
+
+    var replyListenerId = ReplyCommandListener.addListener(callback);
+    ReplyCommandListener.requestIdToListenerId[replyListenerId] = result.requestId;
+};
+
 exports = new MediaControllerManager();
 exports.SearchFilter = SearchFilter;
 exports.RequestReply = RequestReply;
index 3fb6d3f..78f7032 100644 (file)
@@ -1220,42 +1220,63 @@ PlatformResult MediaControllerClient::SendPlaybackState(const std::string& serve
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
+PlatformResult MediaControllerClient::SendPlaybackAction(const std::string& server_name,
+                                                         const std::string& action,
+                                                         const JsonCallback& callback,
+                                                         char** request_id) {
+  ScopeLogger("Action to send: %s", action.c_str());
+  mc_playback_action_e playback_action = MC_PLAYBACK_ACTION_PLAY;
+  PlatformResult result =
+      types::MediaControllerPlaybackActionEnum.getValue(action, &playback_action);
+  if (!result) {
+    LoggerE("MediaControllerPlaybackActionEnum.getValue() failed, error: %s",
+            result.message().c_str());
+    return PlatformResult(ErrorCode::UNKNOWN_ERR);
+  }
+
+  int ret =
+      mc_client_send_playback_action_cmd(handle_, server_name.c_str(), playback_action, request_id);
+  if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
+    return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error sending playback action",
+                              ("mc_client_send_playback_action_cmd() error: %d, message: %s", ret,
+                               get_error_message(ret)));
+  }
+
+  command_reply_callback_ = callback;
+  return PlatformResult(ErrorCode::NO_ERROR);
+}
+
 PlatformResult MediaControllerClient::SendPlaybackPosition(const std::string& server_name,
-                                                           double position) {
+                                                           const unsigned long long position,
+                                                           const JsonCallback& callback,
+                                                           char** request_id) {
   ScopeLogger();
-  /* TODO: Prepare an ACR and propose use case for request_id.
-  char* request_id = nullptr;
-  SCOPE_EXIT {
-    free(request_id);
-  };*/
-  int ret = mc_client_send_playback_position_cmd(handle_, server_name.c_str(),
-                                                 static_cast<unsigned long long>(position),
-                                                 /*&request_id*/ nullptr);
+  int ret =
+      mc_client_send_playback_position_cmd(handle_, server_name.c_str(), position, request_id);
   if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error sending playback position",
                               ("mc_client_send_playback_position_cmd() error: %d, message: %s", ret,
                                get_error_message(ret)));
   }
 
+  command_reply_callback_ = callback;
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
-PlatformResult MediaControllerClient::SendShuffleMode(const std::string& server_name, bool mode) {
+PlatformResult MediaControllerClient::SendShuffleMode(const std::string& server_name,
+                                                      const bool mode, const JsonCallback& callback,
+                                                      char** request_id) {
   ScopeLogger();
-  /* TODO: Prepare an ACR and propose use case for request_id.
-  char* request_id = nullptr;
-  SCOPE_EXIT {
-    free(request_id);
-  };*/
-  int ret = mc_client_send_shuffle_mode_cmd(handle_, server_name.c_str(),
-                                            mode ? MC_SHUFFLE_MODE_ON : MC_SHUFFLE_MODE_OFF,
-                                            /*&request_id*/ nullptr);
+
+  mc_shuffle_mode_e shuffle_mode = mode ? MC_SHUFFLE_MODE_ON : MC_SHUFFLE_MODE_OFF;
+  int ret = mc_client_send_shuffle_mode_cmd(handle_, server_name.c_str(), shuffle_mode, request_id);
   if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
     return LogAndCreateResult(
         ErrorCode::UNKNOWN_ERR, "Error sending shuffle mode",
         ("mc_client_send_shuffle_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
   }
 
+  command_reply_callback_ = callback;
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
@@ -1279,26 +1300,24 @@ PlatformResult MediaControllerClient::SendRepeatMode(const std::string& server_n
 }
 
 PlatformResult MediaControllerClient::SendRepeatState(const std::string& server_name,
-                                                      const std::string& state) {
+                                                      const std::string& state,
+                                                      const JsonCallback& callback,
+                                                      char** request_id) {
   ScopeLogger();
-  /* TODO: Prepare an ACR and propose use case for request_id.
-  char* request_id = nullptr;
-  SCOPE_EXIT {
-    free(request_id);
-  };*/
   mc_repeat_mode_e state_e;
   PlatformResult result = types::MediaControllerRepeatModeEnum.getValue(state, &state_e);
   if (!result) {
     return result;
   }
 
-  int ret = mc_client_send_repeat_mode_cmd(handle_, server_name.c_str(), state_e, nullptr);
+  int ret = mc_client_send_repeat_mode_cmd(handle_, server_name.c_str(), state_e, request_id);
   if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
     return LogAndCreateResult(
         ErrorCode::UNKNOWN_ERR, "Error sending repeat state",
         ("mc_client_send_repeat_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
   }
 
+  command_reply_callback_ = callback;
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
index e4b255b..93cf61d 100644 (file)
@@ -42,10 +42,20 @@ 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 SendPlaybackPosition(const std::string& server_name, double position);
-  common::PlatformResult SendShuffleMode(const std::string& server_name, bool mode);
+  common::PlatformResult SendPlaybackAction(const std::string& server_name,
+                                            const std::string& action, const JsonCallback& callback,
+                                            char** request_id);
+  common::PlatformResult SendPlaybackPosition(const std::string& server_name,
+                                              const unsigned long long position,
+                                              const JsonCallback& callback = nullptr,
+                                              char** request_id = nullptr);
+  common::PlatformResult SendShuffleMode(const std::string& server_name, const bool mode,
+                                         const JsonCallback& callback = nullptr,
+                                         char** request_id = nullptr);
   common::PlatformResult SendRepeatMode(const std::string& server_name, bool mode);
-  common::PlatformResult SendRepeatState(const std::string& server_name, const std::string& state);
+  common::PlatformResult SendRepeatState(const std::string& server_name, const std::string& state,
+                                         const JsonCallback& callback = nullptr,
+                                         char** request_id = nullptr);
   common::PlatformResult SendSearchRequest(const std::string& server_name,
                                            const picojson::value& request,
                                            const JsonCallback& callback, char** request_id);
index ed9cacd..c94f6d4 100644 (file)
@@ -114,6 +114,10 @@ MediaControllerInstance::MediaControllerInstance() {
   REGISTER_METHOD(MediaControllerServerInfoGetIconURI);
   REGISTER_METHOD(MediaControllerClientAddAbilityChangeListener);
   REGISTER_METHOD(MediaControllerClientRemoveAbilityChangeListener);
+  REGISTER_METHOD(MediaControllerServerInfoPlaybackInfoSendPlaybackAction);
+  REGISTER_METHOD(MediaControllerServerInfoPlaybackInfoSendPlaybackPosition);
+  REGISTER_METHOD(MediaControllerServerInfoPlaybackInfoSendShuffleMode);
+  REGISTER_METHOD(MediaControllerServerInfoPlaybackInfoSendRepeatState);
 
   // abilities_info
   REGISTER_METHOD(MediaControllerAbilitiesInfoSubscribe);
@@ -532,6 +536,12 @@ void MediaControllerInstance::MediaControllerServerReplyCommand(const picojson::
   CHECK_EXIST(args, kRequestId, out);
   CHECK_EXIST(args, kReply, out);
 
+  if (args.get(kRequestId).is<picojson::null>()) {
+    LoggerD("The request was sent without reply listener, skipping");
+    ReportSuccess(out);
+    return;
+  }
+
   auto client_name = args.get(kClientName).get<std::string>();
   auto request_id = args.get(kRequestId).get<std::string>();
 
@@ -1226,17 +1236,19 @@ void MediaControllerInstance::MediaControllerServerInfoSendPlaybackPosition(
     return;
   }
 
-  CHECK_EXIST(args, kCallbackId, out)
-  CHECK_EXIST(args, kName, out)
-  CHECK_EXIST(args, kPosition, out)
+  CHECK_ARGS(args, kCallbackId, double, out)
+  CHECK_ARGS(args, kServerName, std::string, out)
+  CHECK_ARGS(args, kPosition, double, out)
 
   auto send = [this, args]() -> void {
     picojson::value response = picojson::value(picojson::object());
     picojson::object& response_obj = response.get<picojson::object>();
     response_obj[kCallbackId] = args.get(kCallbackId);
+    const std::string& server_name = args.get(kServerName).get<std::string>();
+    const unsigned long long position =
+        static_cast<unsigned long long>(args.get(kPosition).get<double>());
 
-    PlatformResult result = client_->SendPlaybackPosition(args.get(kName).get<std::string>(),
-                                                          args.get(kPosition).get<double>());
+    PlatformResult result = client_->SendPlaybackPosition(server_name, position);
 
     if (result) {
       ReportSuccess(response_obj);
@@ -1262,17 +1274,19 @@ void MediaControllerInstance::MediaControllerServerInfoSendShuffleMode(const pic
     return;
   }
 
-  CHECK_EXIST(args, kCallbackId, out)
-  CHECK_EXIST(args, kName, out)
-  CHECK_EXIST(args, kMode, out)
+  CHECK_ARGS(args, kCallbackId, double, out)
+  CHECK_ARGS(args, kServerName, std::string, out)
+  CHECK_ARGS(args, kMode, bool, out)
 
   auto send = [this, args]() -> void {
     picojson::value response = picojson::value(picojson::object());
     picojson::object& response_obj = response.get<picojson::object>();
     response_obj[kCallbackId] = args.get(kCallbackId);
 
-    PlatformResult result =
-        client_->SendShuffleMode(args.get(kName).get<std::string>(), args.get(kMode).get<bool>());
+    const std::string& server_name = args.get(kServerName).get<std::string>();
+    const bool mode = args.get(kMode).get<bool>();
+
+    PlatformResult result = client_->SendShuffleMode(server_name, mode);
 
     if (result) {
       ReportSuccess(response_obj);
@@ -1333,8 +1347,10 @@ void MediaControllerInstance::MediaControllerServerInfoSendRepeatState(const pic
     picojson::object& response_obj = response.get<picojson::object>();
     response_obj[kCallbackId] = args.get(kCallbackId);
 
-    PlatformResult result = client_->SendRepeatState(args.get(kName).get<std::string>(),
-                                                     args.get(kState).get<std::string>());
+    const std::string& server_name = args.get(kServerName).get<std::string>();
+    const std::string& state = args.get(kState).get<std::string>();
+
+    PlatformResult result = client_->SendRepeatState(server_name, state);
 
     if (result) {
       ReportSuccess(response_obj);
@@ -1655,6 +1671,172 @@ void MediaControllerInstance::MediaControllerServerInfoGetIconURI(const picojson
   ReportSuccess(picojson::value(result), out);
 }
 
+void MediaControllerInstance::MediaControllerServerInfoPlaybackInfoSendPlaybackAction(
+    const picojson::value& args, picojson::object& out) {
+  ScopeLogger();
+  if (!client_) {
+    LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, MediaControllerUnknownErrorMsg), &out,
+                      (MediaControllerClientUnknownErrorMsg));
+    return;
+  }
+
+  CHECK_ARGS(args, kServerName, std::string, out)
+  CHECK_ARGS(args, kAttribute, std::string, out)
+  CHECK_ARGS(args, kListenerId, std::string, out)
+
+  JsonCallback reply_cb = [this, args](picojson::value* reply) -> void {
+    if (reply) {
+      picojson::object& reply_obj = reply->get<picojson::object>();
+      reply_obj[kListenerId] = args.get(kListenerId);
+      Instance::PostMessage(this, reply->serialize().c_str());
+    } else {
+      LoggerW("No reply passed to json callback, ignoring");
+    }
+  };
+
+  char* request_id = nullptr;
+  SCOPE_EXIT {
+    free(request_id);
+  };
+
+  const std::string& server_name = args.get(kServerName).get<std::string>();
+  const std::string& action = args.get(kAttribute).get<std::string>();
+
+  PlatformResult result = client_->SendPlaybackAction(server_name, action, reply_cb, &request_id);
+
+  if (result) {
+    ReportSuccess(out);
+    out[kRequestId] = picojson::value(std::string(request_id));
+  } else {
+    LogAndReportError(result, &out, ("Failed to send playback action."));
+  }
+}
+
+void MediaControllerInstance::MediaControllerServerInfoPlaybackInfoSendPlaybackPosition(
+    const picojson::value& args, picojson::object& out) {
+  ScopeLogger();
+  if (!client_) {
+    LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, MediaControllerUnknownErrorMsg), &out,
+                      (MediaControllerClientUnknownErrorMsg));
+    return;
+  }
+
+  CHECK_ARGS(args, kServerName, std::string, out)
+  CHECK_ARGS(args, kAttribute, double, out)
+  CHECK_ARGS(args, kListenerId, std::string, out)
+
+  JsonCallback reply_cb = [this, args](picojson::value* reply) -> void {
+    if (reply) {
+      picojson::object& reply_obj = reply->get<picojson::object>();
+      reply_obj[kListenerId] = args.get(kListenerId);
+      Instance::PostMessage(this, reply->serialize().c_str());
+    } else {
+      LoggerW("No reply passed to json callback, ignoring");
+    }
+  };
+
+  char* request_id = nullptr;
+  SCOPE_EXIT {
+    free(request_id);
+  };
+
+  const std::string& server_name = args.get(kServerName).get<std::string>();
+  const unsigned long long position =
+      static_cast<unsigned long long>(args.get(kAttribute).get<double>());
+
+  PlatformResult result =
+      client_->SendPlaybackPosition(server_name, position, reply_cb, &request_id);
+
+  if (result) {
+    ReportSuccess(out);
+    out[kRequestId] = picojson::value(std::string(request_id));
+  } else {
+    LogAndReportError(result, &out, ("Failed to send playback position."));
+  }
+}
+
+void MediaControllerInstance::MediaControllerServerInfoPlaybackInfoSendShuffleMode(
+    const picojson::value& args, picojson::object& out) {
+  ScopeLogger();
+  if (!client_) {
+    LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, MediaControllerUnknownErrorMsg), &out,
+                      (MediaControllerClientUnknownErrorMsg));
+    return;
+  }
+
+  CHECK_ARGS(args, kServerName, std::string, out)
+  CHECK_ARGS(args, kAttribute, bool, out)
+  CHECK_ARGS(args, kListenerId, std::string, out)
+
+  JsonCallback reply_cb = [this, args](picojson::value* reply) -> void {
+    if (reply) {
+      picojson::object& reply_obj = reply->get<picojson::object>();
+      reply_obj[kListenerId] = args.get(kListenerId);
+      Instance::PostMessage(this, reply->serialize().c_str());
+    } else {
+      LoggerW("No reply passed to json callback, ignoring");
+    }
+  };
+
+  char* request_id = nullptr;
+  SCOPE_EXIT {
+    free(request_id);
+  };
+
+  const std::string& server_name = args.get(kServerName).get<std::string>();
+  const bool mode = args.get(kAttribute).get<bool>();
+
+  PlatformResult result = client_->SendShuffleMode(server_name, mode, reply_cb, &request_id);
+
+  if (result) {
+    ReportSuccess(out);
+    out[kRequestId] = picojson::value(std::string(request_id));
+  } else {
+    LogAndReportError(result, &out, ("Failed to send playback position."));
+  }
+}
+
+void MediaControllerInstance::MediaControllerServerInfoPlaybackInfoSendRepeatState(
+    const picojson::value& args, picojson::object& out) {
+  ScopeLogger();
+  if (!client_) {
+    LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, MediaControllerUnknownErrorMsg), &out,
+                      (MediaControllerClientUnknownErrorMsg));
+    return;
+  }
+
+  CHECK_ARGS(args, kServerName, std::string, out)
+  CHECK_ARGS(args, kAttribute, std::string, out)
+  CHECK_ARGS(args, kListenerId, std::string, out)
+
+  JsonCallback reply_cb = [this, args](picojson::value* reply) -> void {
+    if (reply) {
+      picojson::object& reply_obj = reply->get<picojson::object>();
+      reply_obj[kListenerId] = args.get(kListenerId);
+      Instance::PostMessage(this, reply->serialize().c_str());
+    } else {
+      LoggerW("No reply passed to json callback, ignoring");
+    }
+  };
+
+  char* request_id = nullptr;
+  SCOPE_EXIT {
+    free(request_id);
+  };
+
+  const std::string& server_name = args.get(kServerName).get<std::string>();
+  const std::string& state = args.get(kAttribute).get<std::string>();
+
+  PlatformResult result = client_->SendRepeatState(server_name, state, reply_cb, &request_id);
+
+  if (result) {
+    ReportSuccess(out);
+    out[kRequestId] = picojson::value(std::string(request_id));
+  } else {
+    LogAndReportError(result, &out, ("Failed to send playback position."));
+  }
+}
+
 void MediaControllerInstance::MediaControllerClientAddAbilityChangeListener(
     const picojson::value& args, picojson::object& out) {
   ScopeLogger();
index b73765a..2065c6e 100644 (file)
@@ -127,6 +127,14 @@ class MediaControllerInstance : public common::ParsedInstance {
                                                              picojson::object& out);
   void MediaControllerServerInfoGetAllPlaylists(const picojson::value& args, picojson::object& out);
   void MediaControllerServerInfoGetIconURI(const picojson::value& args, picojson::object& out);
+  void MediaControllerServerInfoPlaybackInfoSendPlaybackAction(const picojson::value& args,
+                                                               picojson::object& out);
+  void MediaControllerServerInfoPlaybackInfoSendPlaybackPosition(const picojson::value& args,
+                                                                 picojson::object& out);
+  void MediaControllerServerInfoPlaybackInfoSendShuffleMode(const picojson::value& args,
+                                                            picojson::object& out);
+  void MediaControllerServerInfoPlaybackInfoSendRepeatState(const picojson::value& args,
+                                                            picojson::object& out);
 
   // abilities_info
   void MediaControllerAbilitiesInfoSubscribe(const picojson::value& args, picojson::object& out);
index 09a22b7..4a297c7 100644 (file)
@@ -1049,6 +1049,7 @@ void MediaControllerServer::OnPlaybackPositionCommand(const char* client_name,
   data_o[kAction] = picojson::value(std::string("onplaybackpositionrequest"));
   data_o[kPosition] = picojson::value(static_cast<double>(position));
   data_o[kClientName] = picojson::value(client_name);
+  data_o[kRequestId] = request_id ? picojson::value(std::string(request_id)) : picojson::value();
 
   server->change_request_playback_info_listener_(&data);
 }
@@ -1088,6 +1089,7 @@ void MediaControllerServer::OnShuffleModeCommand(const char* client_name, const
   data_o[kAction] = picojson::value(std::string("onshufflemoderequest"));
   data_o[kMode] = picojson::value(mode == MC_SHUFFLE_MODE_ON);
   data_o[kClientName] = picojson::value(client_name);
+  data_o[kRequestId] = request_id ? picojson::value(std::string(request_id)) : picojson::value();
 
   server->change_request_playback_info_listener_(&data);
 }
@@ -1119,6 +1121,7 @@ void MediaControllerServer::OnRepeatModeCommand(const char* client_name, const c
   }
   data_o[kAction] = picojson::value(std::string("onrepeatstaterequest"));
   data_o[kState] = picojson::value(state);
+  data_o[kRequestId] = request_id ? picojson::value(std::string(request_id)) : picojson::value();
 
   server->change_request_playback_info_listener_(&data);
 }
index 7af3017..1bad105 100644 (file)
@@ -42,6 +42,7 @@ const char* kAbility = "ability";
 const char* kAbilityType = "abilityType";
 const char* kAction = "action";
 const char* kAgeRating = "ageRating";
+const char* kAttribute = "attribute";
 const char* kCallbackId = "callbackId";
 const char* kCategory = "category";
 const char* kClientName = "clientName";
index e1f5462..f0ca6f5 100644 (file)
@@ -43,6 +43,7 @@ extern const char* kAbility;
 extern const char* kAbilityType;
 extern const char* kAction;
 extern const char* kAgeRating;
+extern const char* kAttribute;
 extern const char* kCallbackId;
 extern const char* kCategory;
 extern const char* kClientName;
index 5f07c4b..21241f1 100644 (file)
@@ -1400,6 +1400,12 @@ NativeManager.prototype.callIfPossible = function(callback) {
     }
 };
 
+NativeManager.prototype.callIfPossibleAndReturn = function(callback) {
+    if (!_type.isNullOrUndefined(callback)) {
+        return callback.apply(callback, [].slice.call(arguments, 1));
+    }
+};
+
 // WebAPIException and WebAPIError definition moved to Utils for compliance
 // reasons with blink-wrt environment.
 // In blink-wrt the original Tizen module is loaded, which is not providing