From: Piotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/삼성전자 Date: Thu, 12 Sep 2019 09:40:52 +0000 (+0200) Subject: [Mediacontroller] added subtitles feature and related ability X-Git-Tag: submit/tizen/20190919.123326~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=30e94edf67eb57d71ab8a471d302a4dc5444a074;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Mediacontroller] added subtitles feature and related ability [ACR] http://suprem.sec.samsung.net/jira/browse/TWDAPI-230 [Verification] Code compiles without errors. Basic test in chrome console works properly. /// 1. adding command listener var mcServer = tizen.mediacontroller.createServer(); mcServer.updatePlaybackState("PLAY"); var changeListener = function(enabled, clientName) { console.log("Subtitles mode change requested to: " + enabled + " by " + clientName); return new tizen.mediacontroller.RequestReply(new tizen.Bundle({"message": "Not allowed"}), 13); }; watcherId = mcServer.subtitles.addChangeRequestListener(changeListener); /// 2. checking NotSupportedError when sending without enabled ability var mcClient = tizen.mediacontroller.getClient(); var mcServerInfo = mcClient.getLatestServerInfo() var enabled = true; mcServerInfo.subtitles.sendRequest(enabled, function(data, code) { console.log( "Server replied with return data: " + JSON.stringify(data) + " and code: " + code); }); /// 3. register listener for mode changes (client side) watcherId = mcServerInfo.subtitles.addModeChangeListener(function(status) { console.log(mcServerInfo.name + " server subtitles mode changed to " + status); }); /// 4. change the value of subtitles (should trigger listener from point 3) mcServer.subtitles.enabled = true /// 5. enable ability of server mcServer.abilities.subtitles = "YES" /// sendRequest again (should trigger listener from point 1) mcServerInfo.subtitles.sendRequest(enabled, function(data, code) { console.log( "Server replied with return data: " + JSON.stringify(data) + " and code: " + code); }); /// 6. register ability change listener and trigger the update var listener = { onsimpleabilitychanged: function(server, type, ability) { console.log(type + " ability changed, server name: " + server.name + ", ability: " + ability); } }; mcClient.addAbilityChangeListener(listener); /// call updates to trigger listener mcServer.abilities.subtitles = "NO" mcServer.abilities.subtitles = "NO" /// Listener should be triggered once Change-Id: I00ad78a44b696a7d885d13499af77cf762e54c7e --- diff --git a/src/mediacontroller/mediacontroller_api.js b/src/mediacontroller/mediacontroller_api.js index 1d3f2fae..037b83fe 100755 --- a/src/mediacontroller/mediacontroller_api.js +++ b/src/mediacontroller/mediacontroller_api.js @@ -358,6 +358,7 @@ var MediaControllerSimpleAbility = { PLAYLIST: 'PLAYLIST', CLIENT_CUSTOM: 'CLIENT_CUSTOM', SEARCH: 'SEARCH', + SUBTITLES: 'SUBTITLES', MODE_360: 'MODE_360' }; @@ -627,6 +628,7 @@ var MediaControllerAbilities = function() { _playlist = MediaControllerAbilitySupport.UNDECIDED, _clientCustom = MediaControllerAbilitySupport.UNDECIDED, _search = MediaControllerAbilitySupport.UNDECIDED, + _subtitles = MediaControllerAbilitySupport.NO, _mode360 = MediaControllerAbilitySupport.NO; Object.defineProperties(this, { @@ -706,6 +708,18 @@ var MediaControllerAbilities = function() { }, enumerable: true }, + subtitles: { + get: function() { + return _subtitles; + }, + set: function(val) { + if (val !== _subtitles) { + setSimpleAbility(MediaControllerSimpleAbility.SUBTITLES, val); + _subtitles = val; + } + }, + enumerable: true + }, mode360: { get: function() { return _mode360; @@ -894,6 +908,16 @@ var MediaControllerAbilitiesInfo = function(serverName) { set: function() {}, enumerable: true }, + subtitles: { + get: function() { + return getSimpleAbility( + serverName, + MediaControllerSimpleAbility.SUBTITLES + ); + }, + set: function() {}, + enumerable: true + }, mode360: { get: function() { return getSimpleAbility( @@ -994,9 +1018,201 @@ var MediaControllerPlaybackAbilitiesInfo = function(serverName) { }); }; -// TODO subtitles -var MediaControllerSubtitles = function() {}; -var MediaControllerSubtitlesInfo = function() {}; +// subtitles +var MediaControllerSubtitles = function() { + // the default value is false + var _enabled = false; + Object.defineProperties(this, { + enabled: { + get: function() { + return _enabled; + }, + set: function(v) { + var data = { + enabled: converter_.toBoolean(v) + }; + if (data.enabled !== _enabled) { + var result = native_.callSync( + 'MediaControllerSubtitles_updateEnabled', + data + ); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + _enabled = data.enabled; + } + }, + enumerable: true + } + }); +}; + +var MediaControllerSubtitlesListener = new ListenerManager( + native_, + '_MediaControllerSubtitlesListener', + function(msg, listener) { + var reply = listener(msg.clientName, msg.enabled); + + if (!(reply instanceof RequestReply)) { + reply = new RequestReply( + xwalk.utils.type.isNullOrUndefined(reply) ? null : reply, + 0 + ); + } + + var nativeData = { + clientName: msg.clientName, + requestId: msg.requestId, + reply: reply + }; + var result = native_.callSync('MediaControllerServer_replyCommand', nativeData); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } +); + +MediaControllerSubtitles.prototype.addChangeRequestListener = function() { + var args = validator_.validateArgs(arguments, [ + { + name: 'listener', + type: types_.FUNCTION, + optional: false, + nullable: false + } + ]); + + if (type_.isEmptyObject(MediaControllerSubtitlesListener.listeners)) { + var result = native_.callSync( + 'MediaControllerSubtitles_addChangeRequestListener', + { + listenerId: MediaControllerSubtitlesListener.listenerName + } + ); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } + return MediaControllerSubtitlesListener.addListener(args.listener); +}; + +MediaControllerSubtitles.prototype.removeChangeRequestListener = function(watchId) { + var args = validator_.validateArgs(arguments, [ + { name: 'watchId', type: types_.LONG } + ]); + + MediaControllerSubtitlesListener.removeListener(args.watchId); + + if (type_.isEmptyObject(MediaControllerSubtitlesListener.listeners)) { + var result = native_.callSync( + 'MediaControllerSubtitles_removeChangeRequestListener' + ); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } +}; + +var SubtitlesChangeListener = new ListenerManager( + native_, + '_SubtitlesChangeListener', + function(msg, listener) { + listener(msg.enabled); + } +); + +var MediaControllerSubtitlesInfo = function(name) { + var _serverName = name; + Object.defineProperties(this, { + enabled: { + get: function() { + var result = native_.callSync('MediaControllerSubtitlesInfo_getEnabled', { + name: _serverName + }); + if (native_.isFailure(result)) { + throw new native_.getErrorObject(result); + } + return native_.getResultObject(result); + }, + set: function(v) {}, + enumerable: true + } + }); + + this.sendRequest = function() { + var args = validator_.validateArgs(arguments, [ + { + name: 'enabled', + type: types_.BOOLEAN + }, + { + name: 'replyCallback', + type: types_.FUNCTION + } + ]); + var callback = function(result) { + native_.callIfPossible( + args.replyCallback, + native_.getResultObject(result).data, + native_.getResultObject(result).code + ); + }; + + var nativeData = { + enabled: args.enabled, + name: _serverName, + listenerId: ReplyCommandListener.listenerName + }; + + var result = native_.callSync( + 'MediaControllerSubtitlesInfo_sendRequest', + nativeData + ); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + + var replyListenerId = ReplyCommandListener.addListener(callback); + ReplyCommandListener.requestIdToListenerId[replyListenerId] = result.requestId; + }; + + this.addModeChangeListener = function(listener) { + var args = validator_.validateArgs(arguments, [ + { name: 'listener', type: types_.FUNCTION } + ]); + + if (type_.isEmptyObject(SubtitlesChangeListener.listeners)) { + var result = native_.callSync( + 'MediaControllerSubtitlesInfo_addModeChangeListener', + { + listenerId: SubtitlesChangeListener.listenerName + } + ); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } + return SubtitlesChangeListener.addServerInfoListener(args.listener, _serverName); + }; + + this.removeModeChangeListener = function(watchId) { + var args = validator_.validateArgs(arguments, [ + { name: 'watchId', type: types_.LONG } + ]); + + SubtitlesChangeListener.removeServerInfoListener(args.watchId); + + if (type_.isEmptyObject(SubtitlesChangeListener.listeners)) { + var result = native_.callSync( + 'MediaControllerSubtitlesInfo_removeModeChangeListener' + ); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + } + }; +}; + // mode360 var MediaControllerMode360 = function() { // the default value is false @@ -2107,7 +2323,7 @@ function MediaControllerServerInfo(data) { writable: false }, subtitles: { - value: new MediaControllerSubtitlesInfo(), + value: new MediaControllerSubtitlesInfo(data.name), enumerable: true, writable: false }, diff --git a/src/mediacontroller/mediacontroller_client.cc b/src/mediacontroller/mediacontroller_client.cc index 4fa5788e..6bbade4d 100644 --- a/src/mediacontroller/mediacontroller_client.cc +++ b/src/mediacontroller/mediacontroller_client.cc @@ -63,6 +63,10 @@ MediaControllerClient::~MediaControllerClient() { LoggerE("Failed to unset ability listener"); } + if (nullptr != subtitles_update_listener_ && !UnsetSubtitlesInfoChangeListener()) { + LoggerE("Failed to unset subtitles listener"); + } + if (nullptr != mode360_update_listener_ && !UnsetMode360InfoChangeListener()) { LoggerE("Failed to unset mode 360 listener"); } @@ -1160,7 +1164,77 @@ PlatformResult MediaControllerClient::UnsetPlaylistUpdateListener() { return PlatformResult(ErrorCode::NO_ERROR); } -// TODO subtitles +// subtitles +PlatformResult MediaControllerClient::GetSubtitlesEnabled(const std::string& name, bool* enabled) { + ScopeLogger(); + + int ret = mc_client_get_server_subtitles_enabled(handle_, name.c_str(), enabled); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error getting subtitle enabled", + ("mc_client_get_server_subtitles_enabled() error: %d, message: %s", + ret, get_error_message(ret))); + } + + return PlatformResult(ErrorCode::NO_ERROR); +} + +PlatformResult MediaControllerClient::SendSubtitlesEnabled(const std::string& server_name, + bool enabled, + const JsonCallback& reply_cb, + char** request_id) { + ScopeLogger(); + int ret = mc_client_send_subtitles_cmd(handle_, server_name.c_str(), enabled, request_id); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult( + utils::ConvertMediaControllerError(ret), "Error sending subtitle command", + ("mc_client_send_subtitles_cmd() error: %d, message: %s", ret, get_error_message(ret))); + } + + command_reply_callback_ = reply_cb; + return PlatformResult(ErrorCode::NO_ERROR); +} + +PlatformResult MediaControllerClient::SetSubtitlesInfoChangeListener(const JsonCallback& callback) { + ScopeLogger(); + + int ret = mc_client_set_subtitles_updated_cb(handle_, OnSubtitlesUpdate, this); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to set subtitles listener", + ("mc_client_set_subtitles_updated_cb() error: %d, message: %s", ret, + get_error_message(ret))); + } + + subtitles_update_listener_ = callback; + + return PlatformResult(ErrorCode::NO_ERROR); +} + +PlatformResult MediaControllerClient::UnsetSubtitlesInfoChangeListener() { + ScopeLogger(); + int ret = mc_client_unset_subtitles_updated_cb(handle_); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to unset subtitles listener", + ("mc_client_unset_subtitles_updated_cb() error: %d, message: %s", ret, + get_error_message(ret))); + } + subtitles_update_listener_ = nullptr; + return PlatformResult(ErrorCode::NO_ERROR); +} + +void MediaControllerClient::OnSubtitlesUpdate(const char* server_name, bool enabled, + void* user_data) { + ScopeLogger(); + MediaControllerClient* client = static_cast(user_data); + + picojson::value data = picojson::value(picojson::object()); + picojson::object& data_o = data.get(); + + data_o["enabled"] = picojson::value(enabled); + data_o["name"] = picojson::value(server_name); + + client->subtitles_update_listener_(&data); +} + // mode360 PlatformResult MediaControllerClient::GetMode360Enabled(const std::string& name, bool* enabled) { ScopeLogger(); diff --git a/src/mediacontroller/mediacontroller_client.h b/src/mediacontroller/mediacontroller_client.h index 9b361776..1acf677a 100644 --- a/src/mediacontroller/mediacontroller_client.h +++ b/src/mediacontroller/mediacontroller_client.h @@ -74,6 +74,11 @@ class MediaControllerClient { common::PlatformResult UnsubscribeServer(const std::string& server_name); common::PlatformResult FindSubscribedServers(picojson::array* servers); // TODO subtitles + common::PlatformResult GetSubtitlesEnabled(const std::string& name, bool* enabled); + common::PlatformResult SendSubtitlesEnabled(const std::string& server_name, bool enabled, + const JsonCallback& reply_cb, char** request_id); + common::PlatformResult SetSubtitlesInfoChangeListener(const JsonCallback& callback); + common::PlatformResult UnsetSubtitlesInfoChangeListener(); // mode360 common::PlatformResult GetMode360Enabled(const std::string& name, bool* enabled); common::PlatformResult SendMode360Enabled(const std::string& server_name, bool enabled, @@ -91,6 +96,8 @@ class MediaControllerClient { JsonCallback command_reply_callback_; JsonCallback playlist_update_listener_; JsonCallback ability_listener_; + // subtitles + JsonCallback subtitles_update_listener_; // mode 360 JsonCallback mode360_update_listener_; @@ -112,7 +119,8 @@ class MediaControllerClient { void* user_data); static void OnSimpleAbilityUpdate(const char* server_name, mc_ability_e type, mc_ability_support_e mode, void* user_data); - // TODO subtitles + // subtitles + static void OnSubtitlesUpdate(const char* server_name, bool enabled, void* user_data); // mode360 static void OnMode360Update(const char* server_name, bool enabled, void* user_data); // TODO displayMode diff --git a/src/mediacontroller/mediacontroller_instance.cc b/src/mediacontroller/mediacontroller_instance.cc index f9b35c73..b959539d 100644 --- a/src/mediacontroller/mediacontroller_instance.cc +++ b/src/mediacontroller/mediacontroller_instance.cc @@ -152,7 +152,21 @@ MediaControllerInstance::MediaControllerInstance() { REGISTER_SYNC("MediaControllerPlaylist_addItem", MediaControllerPlaylistAddItem); REGISTER_ASYNC("MediaControllerPlaylist_getItems", MediaControllerPlaylistGetItems); - // TODO subtitles + // subtitles + REGISTER_SYNC("MediaControllerSubtitles_updateEnabled", MediaControllerSubtitlesUpdateEnabled); + REGISTER_SYNC("MediaControllerSubtitles_addChangeRequestListener", + MediaControllerSubtitlesAddChangeRequestListener); + REGISTER_SYNC("MediaControllerSubtitles_removeChangeRequestListener", + MediaControllerSubtitlesRemoveChangeRequestListener); + + REGISTER_SYNC("MediaControllerSubtitlesInfo_getEnabled", MediaControllerSubtitlesInfoGetEnabled); + REGISTER_ASYNC("MediaControllerSubtitlesInfo_sendRequest", + MediaControllerSubtitlesInfoSendRequest); + REGISTER_SYNC("MediaControllerSubtitlesInfo_addModeChangeListener", + MediaControllerSubtitlesInfoAddModeChangeListener); + REGISTER_SYNC("MediaControllerSubtitlesInfo_removeModeChangeListener", + MediaControllerSubtitlesInfoRemoveModeChangeListener); + // mode360 REGISTER_SYNC("MediaControllerMode360_updateEnabled", MediaControllerMode360UpdateEnabled); REGISTER_SYNC("MediaControllerMode360_addChangeRequestListener", @@ -1597,7 +1611,188 @@ void MediaControllerInstance::MediaControllerPlaylistGetItems(const picojson::va ReportSuccess(out); } -// TODO subtitles +// subtitles +void MediaControllerInstance::MediaControllerSubtitlesUpdateEnabled(const picojson::value& args, + picojson::object& out) { + ScopeLogger(); + + if (!server_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out, + ("Failed: server_")); + return; + } + + CHECK_ARGS(args, "enabled", bool, out); + + const bool enabled = args.get("enabled").get(); + PlatformResult result = server_->UpdateSubtitlesEnabled(enabled); + if (!result) { + LogAndReportError(result, &out, ("Failed server_->UpdateSubtitlesEnabled()")); + return; + } + ReportSuccess(out); +} + +void MediaControllerInstance::MediaControllerSubtitlesAddChangeRequestListener( + const picojson::value& args, picojson::object& out) { + ScopeLogger(); + if (!server_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out, + ("Failed: server_")); + return; + } + + CHECK_ARGS(args, "listenerId", std::string, out) + + JsonCallback callback = [this, args](picojson::value* data) -> void { + if (!data) { + LoggerE("No data passed to json callback"); + return; + } + picojson::object& request_o = data->get(); + request_o["listenerId"] = args.get("listenerId"); + + Instance::PostMessage(this, data->serialize().c_str()); + }; + + auto result = server_->SetSubtitlesChangeRequestListener(callback); + if (!result) { + LogAndReportError(result, &out); + return; + } + + ReportSuccess(out); +} + +void MediaControllerInstance::MediaControllerSubtitlesRemoveChangeRequestListener( + const picojson::value& args, picojson::object& out) { + ScopeLogger(); + if (!server_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out, + ("Failed: server_")); + return; + } + + auto result = server_->UnsetSubtitlesChangeRequestListener(); + if (!result) { + LogAndReportError(result, &out); + return; + } + ReportSuccess(out); +} + +void MediaControllerInstance::MediaControllerSubtitlesInfoGetEnabled(const picojson::value& args, + picojson::object& out) { + ScopeLogger(); + if (!client_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out, + ("Failed: client_")); + return; + } + + CHECK_ARGS(args, "name", std::string, out) + + bool enabled = false; + PlatformResult result = + client_->GetSubtitlesEnabled(args.get("name").get(), &enabled); + + if (!result) { + LogAndReportError(result, &out, ("Failed: client_->GetSubtitlesEnabled")); + return; + } + + ReportSuccess(picojson::value(enabled), out); +} + +void MediaControllerInstance::MediaControllerSubtitlesInfoSendRequest(const picojson::value& args, + picojson::object& out) { + ScopeLogger(); + if (!client_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."), &out, + ("Failed: client_")); + return; + } + + CHECK_ARGS(args, "listenerId", std::string, out) + CHECK_ARGS(args, "name", std::string, out) + CHECK_ARGS(args, "enabled", bool, out) + + JsonCallback reply_cb = [this, args](picojson::value* reply) -> void { + if (reply) { + picojson::object& reply_obj = reply->get(); + reply_obj["listenerId"] = args.get("listenerId"); + 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); + }; + + PlatformResult result = client_->SendSubtitlesEnabled( + args.get("name").get(), args.get("enabled").get(), reply_cb, &request_id); + + if (result) { + ReportSuccess(out); + out["requestId"] = picojson::value(std::string(request_id)); + } else { + LogAndReportError(result, &out, ("Failed to send command.")); + } +} + +void MediaControllerInstance::MediaControllerSubtitlesInfoAddModeChangeListener( + 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, "listenerId", std::string, out) + + JsonCallback callback = [this, args](picojson::value* data) -> void { + if (nullptr == data) { + LoggerE("No data passed to json callback"); + return; + } + + picojson::object& request_o = data->get(); + request_o["listenerId"] = args.get("listenerId"); + + Instance::PostMessage(this, data->serialize().c_str()); + }; + + auto result = client_->SetSubtitlesInfoChangeListener(callback); + if (!result) { + LogAndReportError(result, &out); + return; + } + + ReportSuccess(out); +} + +void MediaControllerInstance::MediaControllerSubtitlesInfoRemoveModeChangeListener( + const picojson::value& args, picojson::object& out) { + ScopeLogger(); + if (!client_) { + LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occured."), &out, + ("Failed: client_")); + return; + } + + auto result = client_->UnsetSubtitlesInfoChangeListener(); + if (!result) { + LogAndReportError(result, &out); + return; + } + + ReportSuccess(out); +} + // mode360 void MediaControllerInstance::MediaControllerMode360UpdateEnabled(const picojson::value& args, picojson::object& out) { diff --git a/src/mediacontroller/mediacontroller_instance.h b/src/mediacontroller/mediacontroller_instance.h index 199fd2c1..b820825a 100644 --- a/src/mediacontroller/mediacontroller_instance.h +++ b/src/mediacontroller/mediacontroller_instance.h @@ -119,7 +119,19 @@ class MediaControllerInstance : public common::ParsedInstance { void MediaControllerPlaylistAddItem(const picojson::value& args, picojson::object& out); void MediaControllerPlaylistGetItems(const picojson::value& args, picojson::object& out); - // TODO subtitles + // subtitles + void MediaControllerSubtitlesUpdateEnabled(const picojson::value& args, picojson::object& out); + void MediaControllerSubtitlesAddChangeRequestListener(const picojson::value& args, + picojson::object& out); + void MediaControllerSubtitlesRemoveChangeRequestListener(const picojson::value& args, + picojson::object& out); + void MediaControllerSubtitlesInfoGetEnabled(const picojson::value& args, picojson::object& out); + void MediaControllerSubtitlesInfoSendRequest(const picojson::value& args, picojson::object& out); + void MediaControllerSubtitlesInfoAddModeChangeListener(const picojson::value& args, + picojson::object& out); + void MediaControllerSubtitlesInfoRemoveModeChangeListener(const picojson::value& args, + picojson::object& out); + // mode360 void MediaControllerMode360UpdateEnabled(const picojson::value& args, picojson::object& out); void MediaControllerMode360AddChangeRequestListener(const picojson::value& args, diff --git a/src/mediacontroller/mediacontroller_server.cc b/src/mediacontroller/mediacontroller_server.cc index 2a4cc72a..5e2a532f 100644 --- a/src/mediacontroller/mediacontroller_server.cc +++ b/src/mediacontroller/mediacontroller_server.cc @@ -60,6 +60,10 @@ MediaControllerServer::~MediaControllerServer() { LoggerE("Failed to unset search request listener"); } + if (nullptr != subtitles_change_request_listener_ && !UnsetSubtitlesChangeRequestListener()) { + LoggerE("Failed to unset subtitles listener"); + } + if (nullptr != mode360_change_request_listener_ && !UnsetMode360ChangeRequestListener()) { LoggerE("Failed to unset mode 360 request listener"); } @@ -1053,7 +1057,65 @@ void MediaControllerServer::OnPlaybackItemCommand(const char* client_name, const server->change_request_playback_info_listener_(&data); } -// TODO subtitles +// subtitles +common::PlatformResult MediaControllerServer::UpdateSubtitlesEnabled(bool enabled) { + ScopeLogger(); + int ret = mc_server_update_subtitles_enabled(handle_, enabled); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error setting server subtitles", + ("mc_server_update_subtitles_enabled() error: %d, message: %s", ret, + get_error_message(ret))); + } + return PlatformResult(ErrorCode::NO_ERROR); +} + +void MediaControllerServer::OnSubtitlesChangeCommand(const char* client_name, + const char* request_id, bool enabled, + void* user_data) { + ScopeLogger(); + + MediaControllerServer* server = static_cast(user_data); + + picojson::value data = picojson::value(picojson::object()); + picojson::object& data_o = data.get(); + + data_o["enabled"] = picojson::value(enabled); + data_o["clientName"] = picojson::value(client_name); + data_o["requestId"] = picojson::value(std::string(request_id)); + + server->subtitles_change_request_listener_(&data); +} + +PlatformResult MediaControllerServer::SetSubtitlesChangeRequestListener( + const JsonCallback& callback) { + ScopeLogger(); + + int ret = mc_server_set_subtitles_cmd_received_cb(handle_, OnSubtitlesChangeCommand, this); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to set subtitles command listener", + ("mc_server_set_subtitles_cmd_received_cb() error: %d, message: %s", + ret, get_error_message(ret))); + } + + subtitles_change_request_listener_ = callback; + + return PlatformResult(ErrorCode::NO_ERROR); +} + +PlatformResult MediaControllerServer::UnsetSubtitlesChangeRequestListener() { + ScopeLogger(); + + int ret = mc_server_unset_subtitles_cmd_received_cb(handle_); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to unset subtitles command listener", + ("mc_server_unset_subtitles_cmd_received_cb() error: %d, message: %s", + ret, get_error_message(ret))); + } + subtitles_change_request_listener_ = nullptr; + + return PlatformResult(ErrorCode::NO_ERROR); +} + // mode360 common::PlatformResult MediaControllerServer::UpdateMode360Enabled(bool enabled) { ScopeLogger(); diff --git a/src/mediacontroller/mediacontroller_server.h b/src/mediacontroller/mediacontroller_server.h index 7c79faa3..6a401372 100644 --- a/src/mediacontroller/mediacontroller_server.h +++ b/src/mediacontroller/mediacontroller_server.h @@ -69,7 +69,11 @@ class MediaControllerServer { common::PlatformResult SavePlaybackAbilities(const picojson::value& abilities); common::PlatformResult SetSimpleAbility(const std::string& ability_type, const std::string& support_str); - // TODO subtitles + // 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); @@ -111,7 +115,10 @@ class MediaControllerServer { mc_search_h request, void* user_data); static void OnCommandReceived(const char* client_name, const char* request_id, const char* command, bundle* data, void* user_data); - // TODO subtitles + // subtitles + JsonCallback subtitles_change_request_listener_; + static void OnSubtitlesChangeCommand(const char* client_name, const char* request_id, + bool enabled, void* user_data); // mode360 JsonCallback mode360_change_request_listener_; static void OnMode360ChangeCommand(const char* client_name, const char* request_id, bool enabled, diff --git a/src/mediacontroller/mediacontroller_utils.cc b/src/mediacontroller/mediacontroller_utils.cc index 4aa1d0ca..6bd2af37 100644 --- a/src/mediacontroller/mediacontroller_utils.cc +++ b/src/mediacontroller/mediacontroller_utils.cc @@ -111,6 +111,7 @@ const common::PlatformEnum MediaControllerSimpleAbilityEnum{ {"PLAYLIST", MC_ABILITY_PLAYLIST}, {"CLIENT_CUSTOM", MC_ABILITY_CLIENT_CUSTOM}, {"SEARCH", MC_ABILITY_SEARCH}, + {"SUBTITLES", MC_ABILITY_SUBTITLES}, {"MODE_360", MC_ABILITY_360_MODE}}; PlatformResult ConvertPlaybackState(mc_playback_h playback_h, std::string* state) {