2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "mediacontroller/mediacontroller_client.h"
20 #include <bundle_internal.h>
23 #include "common/logger.h"
24 #include "common/scope_exit.h"
25 #include "common/tools.h"
28 namespace mediacontroller {
30 using common::PlatformResult;
31 using common::ErrorCode;
32 using common::tools::ReportError;
33 using common::tools::ReportSuccess;
35 MediaControllerClient::MediaControllerClient() : handle_(nullptr) {
39 MediaControllerClient::~MediaControllerClient() {
42 int ret = mc_client_unset_cmd_reply_received_cb(handle_);
43 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
44 LoggerE("Failed to unset cmd reply callback. Error code: %d; Error message: %s", ret,
45 get_error_message(ret));
48 if (nullptr != server_status_listener_ && !UnsetServerStatusChangeListener()) {
49 LoggerE("Failed to unset server status change listener");
52 if (nullptr != playback_info_listener_ && !UnsetPlaybackInfoListener()) {
53 LoggerE("Failed to unset playback info listener");
56 if (nullptr != playlist_update_listener_ && !UnsetPlaylistUpdateListener()) {
57 LoggerE("Failed to unset playlist update listener");
60 if (nullptr != handle_ && MEDIA_CONTROLLER_ERROR_NONE != mc_client_destroy(handle_)) {
61 LoggerE("Unable to destroy media controller client");
65 PlatformResult MediaControllerClient::Init() {
67 int ret = mc_client_create(&handle_);
68 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
69 return LogAndCreateResult(
70 ErrorCode::UNKNOWN_ERR, "Unable to create media controller client",
71 ("mc_client_create() error: %d, message: %s", ret, get_error_message(ret)));
74 ret = mc_client_set_cmd_reply_received_cb(handle_, OnCommandReply, this);
75 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
76 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
77 "Unable to register cmd reply received callback",
78 ("mc_client_set_cmd_reply_received_cb() error: %d, message: %s", ret,
79 get_error_message(ret)));
82 return PlatformResult(ErrorCode::NO_ERROR);
85 PlatformResult MediaControllerClient::FindServers(picojson::array* servers) {
89 ret = mc_client_foreach_server(handle_, FindServersCallback, servers);
90 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
91 return LogAndCreateResult(
92 ErrorCode::UNKNOWN_ERR, "Unable to fetch active servers, error",
93 ("mc_client_foreach_server() error: %d, message: %s", ret, get_error_message(ret)));
96 // check latest server state - if exist
97 picojson::value latest_server = picojson::value();
98 PlatformResult result = GetLatestServerInfo(&latest_server);
100 LoggerE("GetLatestServerInfo failed, error: %s", result.message().c_str());
104 if (latest_server.is<picojson::null>()) {
105 LoggerD("No latest server available");
106 return PlatformResult(ErrorCode::NO_ERROR);
109 const std::string& latest_name = latest_server.get("name").get<std::string>();
111 // update current server state in list
112 for (auto& it : *servers) {
113 picojson::object& server = it.get<picojson::object>();
114 if (server["name"].get<std::string>() == latest_name) {
115 server["state"] = latest_server.get("state");
120 return PlatformResult(ErrorCode::NO_ERROR);
123 bool MediaControllerClient::FindServersCallback(const char* server_name, void* user_data) {
125 picojson::array* servers = static_cast<picojson::array*>(user_data);
127 picojson::value server = picojson::value(picojson::object());
128 picojson::object& server_o = server.get<picojson::object>();
129 server_o["name"] = picojson::value(std::string(server_name));
130 // active by default in CAPI
131 server_o["state"] = picojson::value(std::string("ACTIVE"));
133 servers->push_back(server);
138 PlatformResult MediaControllerClient::GetLatestServerInfo(picojson::value* server_info) {
142 char* name = nullptr;
146 mc_server_state_e state;
147 ret = mc_client_get_latest_server_info(handle_, &name, &state);
148 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
149 return LogAndCreateResult(
150 ErrorCode::UNKNOWN_ERR, "Error getting latest server info",
151 ("mc_client_get_latest_server_info() error: %d, message: %s", ret, get_error_message(ret)));
155 LoggerD("No active server available");
156 return PlatformResult(ErrorCode::NO_ERROR);
159 std::string state_str;
160 PlatformResult result = types::MediaControllerServerStateEnum.getName(state, &state_str);
162 LoggerE("MediaControllerServerStateEnum.getName() failed, error: %s", result.message().c_str());
166 *server_info = picojson::value(picojson::object());
167 picojson::object& obj = server_info->get<picojson::object>();
168 obj["name"] = picojson::value(std::string(name));
169 obj["state"] = picojson::value(state_str);
171 return PlatformResult(ErrorCode::NO_ERROR);
174 PlatformResult MediaControllerClient::GetPlaybackInfo(const std::string& server_name,
175 picojson::object* playback_info) {
179 char* index = nullptr;
180 char* playlist_name = nullptr;
181 mc_playback_h playback_h;
182 ret = mc_client_get_server_playback_info(handle_, server_name.c_str(), &playback_h);
183 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
184 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error getting playback info",
185 ("mc_client_get_server_playback_info() error: %d, message: %s", ret,
186 get_error_message(ret)));
190 mc_client_destroy_playback(playback_h);
197 PlatformResult result = types::ConvertPlaybackState(playback_h, &state);
199 LoggerE("ConvertPlaybackState failed, error: %s", result.message().c_str());
205 result = types::ConvertPlaybackPosition(playback_h, &position);
207 LoggerE("ConvertPlaybackPosition failed, error: %s", result.message().c_str());
211 // content age rating
213 result = types::ConvertContentAgeRating(playback_h, &rating);
215 LoggerE("ConvertContentAgeRating failed, error: %s", result.message().c_str());
220 mc_shuffle_mode_e shuffle;
221 ret = mc_client_get_server_shuffle_mode(handle_, server_name.c_str(), &shuffle);
222 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
223 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error getting shuffle mode",
224 ("mc_client_get_server_shuffle_mode() error: %d, message: %s", ret,
225 get_error_message(ret)));
229 mc_repeat_mode_e repeat;
230 ret = mc_client_get_server_repeat_mode(handle_, server_name.c_str(), &repeat);
231 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
232 return LogAndCreateResult(
233 ErrorCode::UNKNOWN_ERR, "Error getting repeat mode",
234 ("mc_client_get_server_repeat_mode() error: %d, message: %s", ret, get_error_message(ret)));
238 picojson::value metadata = picojson::value(picojson::object());
239 result = GetMetadata(server_name, &metadata.get<picojson::object>());
244 ret = mc_client_get_playlist_item_info(playback_h, &playlist_name, &index);
245 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
246 return LogAndCreateResult(
247 ErrorCode::UNKNOWN_ERR, "Error getting playlistName and index",
248 ("mc_client_get_playlist_item_info() error: %d, message: %s", ret, get_error_message(ret)));
251 // fill return object
252 (*playback_info)["state"] = picojson::value(state);
253 (*playback_info)["position"] = picojson::value(position);
254 (*playback_info)["ageRating"] = picojson::value(rating);
255 (*playback_info)["shuffleMode"] = picojson::value(shuffle == MC_SHUFFLE_MODE_ON);
256 (*playback_info)["repeatMode"] = picojson::value(repeat == MC_REPEAT_MODE_ON);
257 (*playback_info)["metadata"] = metadata;
258 (*playback_info)["index"] = picojson::value(std::string(index ? index : ""));
259 (*playback_info)["playlistName"] =
260 picojson::value(std::string(playlist_name ? playlist_name : ""));
262 return PlatformResult(ErrorCode::NO_ERROR);
265 PlatformResult MediaControllerClient::GetMetadata(const std::string& server_name,
266 picojson::object* metadata) {
270 mc_metadata_h metadata_h = nullptr;
271 ret = mc_client_get_server_metadata(handle_, server_name.c_str(), &metadata_h);
272 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
273 return LogAndCreateResult(
274 ErrorCode::UNKNOWN_ERR, "Error getting server metadata",
275 ("mc_client_get_server_metadata() error: %d, message: %s", ret, get_error_message(ret)));
279 mc_metadata_destroy(metadata_h);
282 PlatformResult result = types::ConvertMetadata(metadata_h, metadata);
287 return PlatformResult(ErrorCode::NO_ERROR);
290 PlatformResult MediaControllerClient::SetServerStatusChangeListener(const JsonCallback& callback) {
293 int ret = mc_client_set_server_updated_cb(handle_, OnServerStatusUpdate, this);
294 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
295 return LogAndCreateResult(
296 ErrorCode::UNKNOWN_ERR, "Unable to set server status listener",
297 ("mc_client_set_server_updated_cb() error: %d, message: %s", ret, get_error_message(ret)));
300 server_status_listener_ = callback;
302 return PlatformResult(ErrorCode::NO_ERROR);
305 PlatformResult MediaControllerClient::UnsetServerStatusChangeListener() {
307 int ret = mc_client_unset_server_updated_cb(handle_);
308 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
309 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to unset server status listener",
310 ("mc_client_unset_server_updated_cb() error: %d, message: %s", ret,
311 get_error_message(ret)));
313 server_status_listener_ = nullptr;
314 return PlatformResult(ErrorCode::NO_ERROR);
317 void MediaControllerClient::OnServerStatusUpdate(const char* server_name, mc_server_state_e state,
320 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
323 std::string state_str;
324 PlatformResult result = types::MediaControllerServerStateEnum.getName(state, &state_str);
326 LoggerE("MediaControllerServerStateEnum.getName() failed, error: %s", result.message().c_str());
330 picojson::value data = picojson::value(picojson::object());
331 picojson::object& data_o = data.get<picojson::object>();
333 data_o["state"] = picojson::value(state_str);
334 data_o["name"] = picojson::value(server_name);
336 client->server_status_listener_(&data);
339 PlatformResult MediaControllerClient::SetPlaybackInfoListener(const JsonCallback& callback) {
341 int failed_setter = 0;
343 // Lambda function used to clean all set listeners (in case of failure of
344 // SetPlaybackInfoListener method).
345 // The purpose of this lambda is to unset as many setters as we can in case of failure.
347 int (*unsetters[])(mc_client_h) = {
348 mc_client_unset_playback_updated_cb, mc_client_unset_shuffle_mode_updated_cb,
349 mc_client_unset_repeat_mode_updated_cb,
350 /*mc_client_unset_metadata_updated_cb the last unsetter will never be used*/};
352 // This loop is no-op in case of success.
353 for (int i = 0; i < failed_setter; ++i) {
354 auto ret = unsetters[i](handle_);
355 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
356 LoggerE("Fail (%d) returned by the [%d] unsetter", ret, i);
361 int ret = mc_client_set_playback_updated_cb(handle_, OnPlaybackUpdate, this);
362 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
363 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register playback listener",
364 ("mc_client_set_playback_updated_cb() error: %d, message: %s", ret,
365 get_error_message(ret)));
368 ret = mc_client_set_shuffle_mode_updated_cb(handle_, OnShuffleModeUpdate, this);
369 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
371 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register shuffle mode listener",
372 ("mc_client_set_shuffle_mode_updated_cb() error: %d, message: %s",
373 ret, get_error_message(ret)));
376 ret = mc_client_set_repeat_mode_updated_cb(handle_, OnRepeatModeUpdate, this);
377 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
379 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register repeat mode listener",
380 ("mc_client_set_repeat_mode_updated_cb() error: %d, message: %s", ret,
381 get_error_message(ret)));
384 ret = mc_client_set_metadata_updated_cb(handle_, OnMetadataUpdate, this);
385 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
387 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register metadata listener",
388 ("mc_client_set_metadata_updated_cb() error: %d, message: %s", ret,
389 get_error_message(ret)));
392 playback_info_listener_ = callback;
394 return PlatformResult(ErrorCode::NO_ERROR);
397 PlatformResult MediaControllerClient::UnsetPlaybackInfoListener() {
399 // Even though if one of below functions fails, let's try to unset as much listeners as we can.
400 // In the Javascript layer, the removePlaybackInfoChangeListener() method always succeeds, so we
401 // do not need to catch the returned value.
403 mc_client_unset_playback_updated_cb(handle_);
404 mc_client_unset_shuffle_mode_updated_cb(handle_);
405 mc_client_unset_repeat_mode_updated_cb(handle_);
406 mc_client_unset_metadata_updated_cb(handle_);
408 playback_info_listener_ = nullptr;
410 return PlatformResult(ErrorCode::NO_ERROR);
413 void MediaControllerClient::OnPlaybackUpdate(const char* server_name, mc_playback_h playback,
416 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
420 PlatformResult result = types::ConvertPlaybackState(playback, &state);
422 LoggerE("ConvertPlaybackState failed, error: %s", result.message().c_str());
428 result = types::ConvertPlaybackPosition(playback, &position);
430 LoggerE("ConvertPlaybackPosition failed, error: %s", result.message().c_str());
434 picojson::value data = picojson::value(picojson::object());
435 picojson::object& data_o = data.get<picojson::object>();
437 data_o["action"] = picojson::value(std::string("onplaybackchanged"));
438 data_o["state"] = picojson::value(state);
439 data_o["position"] = picojson::value(position);
440 data_o["name"] = picojson::value(server_name);
442 client->playback_info_listener_(&data);
445 void MediaControllerClient::OnShuffleModeUpdate(const char* server_name, mc_shuffle_mode_e mode,
448 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
450 picojson::value data = picojson::value(picojson::object());
451 picojson::object& data_o = data.get<picojson::object>();
453 data_o["action"] = picojson::value(std::string("onshufflemodechanged"));
454 data_o["mode"] = picojson::value(mode == MC_SHUFFLE_MODE_ON);
455 data_o["name"] = picojson::value(server_name);
457 client->playback_info_listener_(&data);
460 void MediaControllerClient::OnRepeatModeUpdate(const char* server_name, mc_repeat_mode_e mode,
463 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
465 picojson::value data = picojson::value(picojson::object());
466 picojson::object& data_o = data.get<picojson::object>();
468 data_o["name"] = picojson::value(server_name);
469 if (MC_REPEAT_MODE_ONE_MEDIA != mode) {
470 // The onrepeatmodechanged event may be reported only with mode equal to true/false. The 3rd
471 // mode is not supported by this event.
472 common::tools::PrintDeprecationWarningFor("onrepeatmodechanged", "onrepeatstatechanged");
473 data_o["action"] = picojson::value(std::string("onrepeatmodechanged"));
474 data_o["mode"] = picojson::value(mode == MC_REPEAT_MODE_ON);
475 client->playback_info_listener_(&data);
478 PlatformResult result = types::MediaControllerRepeatModeEnum.getName(mode, &state);
480 LoggerE("MediaControllerRepeatModeEnum.getName() failed, error: %s", result.message().c_str());
483 data_o["action"] = picojson::value(std::string("onrepeatstatechanged"));
484 data_o["state"] = picojson::value(state);
486 client->playback_info_listener_(&data);
489 void MediaControllerClient::OnMetadataUpdate(const char* server_name, mc_metadata_h metadata_h,
492 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
494 picojson::value data = picojson::value(picojson::object());
495 picojson::object& data_o = data.get<picojson::object>();
497 picojson::value metadata = picojson::value(picojson::object());
498 PlatformResult result = types::ConvertMetadata(metadata_h, &metadata.get<picojson::object>());
500 LoggerE("ConvertMetadata failed, error: %s", result.message().c_str());
504 data_o["action"] = picojson::value(std::string("onmetadatachanged"));
505 data_o["metadata"] = metadata;
506 data_o["name"] = picojson::value(server_name);
508 client->playback_info_listener_(&data);
511 PlatformResult MediaControllerClient::SendCommand(const std::string& server_name,
512 const std::string& command,
513 const picojson::value& data,
514 const JsonCallback& reply_cb, char** request_id) {
516 bundle* bundle = bundle_create();
522 ret = bundle_add(bundle, "data", data.serialize().c_str());
523 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
524 return LogAndCreateResult(
525 ErrorCode::UNKNOWN_ERR, "Unable to add data to bundle",
526 ("bundle_add(data) error: %d, message: %s", ret, get_error_message(ret)));
530 mc_client_send_custom_cmd(handle_, server_name.c_str(), command.c_str(), bundle, request_id);
531 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
532 return LogAndCreateResult(
533 ErrorCode::UNKNOWN_ERR, "Error sending custom command",
534 ("mc_client_send_custom_cmd() error: %d, message: %s", ret, get_error_message(ret)));
537 command_reply_callback_ = reply_cb;
539 return PlatformResult(ErrorCode::NO_ERROR);
542 void MediaControllerClient::OnCommandReply(const char* server_name, const char* request_id,
543 int result_code, bundle* bundle, void* user_data) {
545 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
547 picojson::value out = picojson::value(picojson::object());
548 picojson::object& out_o = out.get<picojson::object>();
549 picojson::value reply = picojson::value(picojson::object());
550 picojson::object& reply_o = reply.get<picojson::object>();
553 char* data_str = nullptr;
558 ret = bundle_get_str(bundle, "data", &data_str);
559 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
560 LoggerE("bundle_get_str(data) failed, error: %d", ret);
562 client->command_reply_callback_(&out);
566 picojson::value data;
568 picojson::parse(data, data_str, data_str + strlen(data_str), &err);
570 LoggerE("Failed to parse bundle data: %s", err.c_str());
572 client->command_reply_callback_(&out);
575 reply_o["data"] = data;
576 reply_o["name"] = picojson::value(server_name);
578 if (nullptr == request_id) {
579 LoggerE("Request id is null.");
581 client->command_reply_callback_(&out);
584 out_o["requestId"] = picojson::value(std::string(request_id));
586 ReportSuccess(reply, out_o);
587 client->command_reply_callback_(&out);
590 PlatformResult MediaControllerClient::SendPlaybackState(const std::string& server_name,
591 const std::string& state) {
593 // In Native API, since Tizen 5.0 an action instead of a state is sent to change the state of a
594 // server. In Web API the names were not refactored.
595 mc_playback_action_e action_e;
596 PlatformResult result = types::MediaControllerPlaybackActionEnum.getValue(state, &action_e);
601 /* TODO: Prepare an ACR and propose use case for request_id.
602 char* request_id = nullptr;
606 int ret = mc_client_send_playback_action_cmd(handle_, server_name.c_str(), action_e, nullptr);
607 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
608 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error sending playback state",
609 ("mc_client_send_playback_action_cmd() error: %d, message: %s", ret,
610 get_error_message(ret)));
613 return PlatformResult(ErrorCode::NO_ERROR);
616 PlatformResult MediaControllerClient::SendPlaybackPosition(const std::string& server_name,
619 /* TODO: Prepare an ACR and propose use case for request_id.
620 char* request_id = nullptr;
624 int ret = mc_client_send_playback_position_cmd(handle_, server_name.c_str(),
625 static_cast<unsigned long long>(position),
626 /*&request_id*/ nullptr);
627 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
628 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error sending playback position",
629 ("mc_client_send_playback_position_cmd() error: %d, message: %s", ret,
630 get_error_message(ret)));
633 return PlatformResult(ErrorCode::NO_ERROR);
636 PlatformResult MediaControllerClient::SendShuffleMode(const std::string& server_name, bool mode) {
638 /* TODO: Prepare an ACR and propose use case for request_id.
639 char* request_id = nullptr;
643 int ret = mc_client_send_shuffle_mode_cmd(handle_, server_name.c_str(),
644 mode ? MC_SHUFFLE_MODE_ON : MC_SHUFFLE_MODE_OFF,
645 /*&request_id*/ nullptr);
646 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
647 return LogAndCreateResult(
648 ErrorCode::UNKNOWN_ERR, "Error sending shuffle mode",
649 ("mc_client_send_shuffle_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
652 return PlatformResult(ErrorCode::NO_ERROR);
655 PlatformResult MediaControllerClient::SendRepeatMode(const std::string& server_name, bool mode) {
657 /* TODO: Prepare an ACR and propose use case for request_id.
658 char* request_id = nullptr;
662 int ret = mc_client_send_repeat_mode_cmd(handle_, server_name.c_str(),
663 mode ? MC_REPEAT_MODE_ON : MC_REPEAT_MODE_OFF,
664 /*&request_id*/ nullptr);
665 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
666 return LogAndCreateResult(
667 ErrorCode::UNKNOWN_ERR, "Error sending repeat mode",
668 ("mc_client_send_repeat_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
671 return PlatformResult(ErrorCode::NO_ERROR);
674 PlatformResult MediaControllerClient::SendRepeatState(const std::string& server_name,
675 const std::string& state) {
677 /* TODO: Prepare an ACR and propose use case for request_id.
678 char* request_id = nullptr;
682 mc_repeat_mode_e state_e;
683 PlatformResult result = types::MediaControllerRepeatModeEnum.getValue(state, &state_e);
688 int ret = mc_client_send_repeat_mode_cmd(handle_, server_name.c_str(), state_e, nullptr);
689 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
690 return LogAndCreateResult(
691 ErrorCode::UNKNOWN_ERR, "Error sending repeat state",
692 ("mc_client_send_repeat_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
695 return PlatformResult(ErrorCode::NO_ERROR);
698 PlatformResult MediaControllerClient::SendPlaybackItem(const std::string& name,
699 const std::string& playlist_name,
700 const std::string& index,
701 const std::string& state, double position) {
704 // In Native API, since Tizen 5.0 an action instead of a state is sent to change the state of a
705 // server. In Web API the names were not refactored.
706 mc_playback_action_e action_e;
707 PlatformResult result = types::MediaControllerPlaybackActionEnum.getValue(state, &action_e);
712 auto position_ull = static_cast<unsigned long long>(position);
713 int ret = mc_client_send_playlist_cmd(handle_, name.c_str(), playlist_name.c_str(), index.c_str(),
714 action_e, position_ull, nullptr);
716 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
717 return LogAndCreateResult(
718 ErrorCode::UNKNOWN_ERR, "Error sending playlist item",
719 ("mc_client_send_playlist_cmd() error: %d, message: %s", ret, get_error_message(ret)));
722 return PlatformResult(ErrorCode::NO_ERROR);
725 void MediaControllerClient::OnPlaylistUpdate(const char* server_name,
726 mc_playlist_update_mode_e mode,
727 const char* playlist_name, mc_playlist_h playlist,
730 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
732 picojson::value data = picojson::value(picojson::object());
733 picojson::object& data_o = data.get<picojson::object>();
735 if (MC_PLAYLIST_UPDATED == mode) {
736 // Create or Update playlist
737 data_o["action"] = picojson::value(std::string("onplaylistupdated"));
739 data_o["action"] = picojson::value(std::string("onplaylistdeleted"));
742 data_o["name"] = picojson::value(std::string(playlist_name));
743 data_o["serverName"] = picojson::value(std::string(server_name));
745 client->playlist_update_listener_(&data);
748 PlatformResult MediaControllerClient::SetPlaylistUpdateListener(const JsonCallback& callback) {
751 int ret = mc_client_set_playlist_updated_cb(handle_, OnPlaylistUpdate, this);
753 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
754 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to add playlist listener",
755 ("mc_client_set_playlist_updated_cb() error: %d, message: %s", ret,
756 get_error_message(ret)));
759 playlist_update_listener_ = callback;
761 return PlatformResult(ErrorCode::NO_ERROR);
764 PlatformResult MediaControllerClient::UnsetPlaylistUpdateListener() {
767 int ret = mc_client_unset_playlist_updated_cb(handle_);
769 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
770 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to remove playlist listener",
771 ("mc_client_unset_playlist_updated_cb() error: %d, message: %s", ret,
772 get_error_message(ret)));
775 playlist_update_listener_ = nullptr;
777 return PlatformResult(ErrorCode::NO_ERROR);
780 } // namespace mediacontroller
781 } // namespace extension