From c3ec8aa45a4d32e63dfd13c70c25f08e3aba0c19 Mon Sep 17 00:00:00 2001 From: Rafal Galka Date: Wed, 22 Apr 2015 09:06:44 +0200 Subject: [PATCH] [MediaController] Playback state implementation - (client) send playback state - (server) onplaybackstaterequest listener Change-Id: I2c9110d3ec23932b494e0f186c8ccc0e8cab0946 Signed-off-by: Rafal Galka --- src/mediacontroller/mediacontroller_api.js | 26 ++++-- src/mediacontroller/mediacontroller_client.cc | 26 ++++++ src/mediacontroller/mediacontroller_client.h | 3 + .../mediacontroller_instance.cc | 81 ++++++++++++++----- src/mediacontroller/mediacontroller_server.cc | 62 ++++++++++++++ src/mediacontroller/mediacontroller_server.h | 9 +++ 6 files changed, 181 insertions(+), 26 deletions(-) diff --git a/src/mediacontroller/mediacontroller_api.js b/src/mediacontroller/mediacontroller_api.js index 9d296db3..1c1b774f 100644 --- a/src/mediacontroller/mediacontroller_api.js +++ b/src/mediacontroller/mediacontroller_api.js @@ -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); } diff --git a/src/mediacontroller/mediacontroller_client.cc b/src/mediacontroller/mediacontroller_client.cc index 282dc67f..2fd88b44 100644 --- a/src/mediacontroller/mediacontroller_client.cc +++ b/src/mediacontroller/mediacontroller_client.cc @@ -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(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 diff --git a/src/mediacontroller/mediacontroller_client.h b/src/mediacontroller/mediacontroller_client.h index f9043449..eb362665 100644 --- a/src/mediacontroller/mediacontroller_client.h +++ b/src/mediacontroller/mediacontroller_client.h @@ -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_; diff --git a/src/mediacontroller/mediacontroller_instance.cc b/src/mediacontroller/mediacontroller_instance.cc index 1cb869c9..f171f091 100644 --- a/src/mediacontroller/mediacontroller_instance.cc +++ b/src/mediacontroller/mediacontroller_instance.cc @@ -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(); + 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(); + 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(args.get("callbackId").get()); + auto send = [this, args]() -> void { + LOGGER(DEBUG) << "entered"; - // implement it + picojson::value response = picojson::value(picojson::object()); + picojson::object& response_obj = response.get(); + response_obj["callbackId"] = args.get("callbackId"); - // call ReplyAsync in later (Asynchronously) + PlatformResult result = client_->SendPlaybackState( + args.get("name").get(), + args.get("state").get()); - // 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( diff --git a/src/mediacontroller/mediacontroller_server.cc b/src/mediacontroller/mediacontroller_server.cc index 5ecd7aaa..23c409c4 100644 --- a/src/mediacontroller/mediacontroller_server.cc +++ b/src/mediacontroller/mediacontroller_server.cc @@ -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(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(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(); + + 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 diff --git a/src/mediacontroller/mediacontroller_server.h b/src/mediacontroller/mediacontroller_server.h index 8ac75bc0..427181e7 100644 --- a/src/mediacontroller/mediacontroller_server.h +++ b/src/mediacontroller/mediacontroller_server.h @@ -9,6 +9,7 @@ #include #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 -- 2.34.1