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"
27 #include "mediacontroller/mediacontroller_types.h"
30 namespace mediacontroller {
32 using common::PlatformResult;
33 using common::ErrorCode;
34 using common::tools::ReportError;
35 using common::tools::ReportSuccess;
37 MediaControllerClient::MediaControllerClient() : handle_(nullptr) {
41 MediaControllerClient::~MediaControllerClient() {
44 int ret = mc_client_unset_cmd_reply_received_cb(handle_);
45 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
46 LoggerE("Failed to unset cmd reply callback. Error code: %d; Error message: %s", ret,
47 get_error_message(ret));
50 if (nullptr != server_status_listener_ && !UnsetServerStatusChangeListener()) {
51 LoggerE("Failed to unset server status change listener");
54 if (nullptr != playback_info_listener_ && !UnsetPlaybackInfoListener()) {
55 LoggerE("Failed to unset playback info listener");
58 if (nullptr != handle_ && MEDIA_CONTROLLER_ERROR_NONE != mc_client_destroy(handle_)) {
59 LoggerE("Unable to destroy media controller client");
63 PlatformResult MediaControllerClient::Init() {
65 int ret = mc_client_create(&handle_);
66 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
67 return LogAndCreateResult(
68 ErrorCode::UNKNOWN_ERR, "Unable to create media controller client",
69 ("mc_client_create() error: %d, message: %s", ret, get_error_message(ret)));
72 ret = mc_client_set_cmd_reply_received_cb(handle_, OnCommandReply, this);
73 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
74 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
75 "Unable to register cmd reply received callback",
76 ("mc_client_set_cmd_reply_received_cb() error: %d, message: %s", ret,
77 get_error_message(ret)));
80 return PlatformResult(ErrorCode::NO_ERROR);
83 PlatformResult MediaControllerClient::FindServers(picojson::array* servers) {
87 ret = mc_client_foreach_server(handle_, FindServersCallback, servers);
88 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
89 return LogAndCreateResult(
90 ErrorCode::UNKNOWN_ERR, "Unable to fetch active servers, error",
91 ("mc_client_foreach_server() error: %d, message: %s", ret, get_error_message(ret)));
94 // check latest server state - if exist
95 picojson::value latest_server = picojson::value();
96 PlatformResult result = GetLatestServerInfo(&latest_server);
98 LoggerE("GetLatestServerInfo failed, error: %s", result.message().c_str());
102 if (latest_server.is<picojson::null>()) {
103 LoggerD("No latest server available");
104 return PlatformResult(ErrorCode::NO_ERROR);
107 const std::string& latest_name = latest_server.get("name").get<std::string>();
109 // update current server state in list
110 for (auto& it : *servers) {
111 picojson::object& server = it.get<picojson::object>();
112 if (server["name"].get<std::string>() == latest_name) {
113 server["state"] = latest_server.get("state");
118 return PlatformResult(ErrorCode::NO_ERROR);
121 bool MediaControllerClient::FindServersCallback(const char* server_name, void* user_data) {
123 picojson::array* servers = static_cast<picojson::array*>(user_data);
125 picojson::value server = picojson::value(picojson::object());
126 picojson::object& server_o = server.get<picojson::object>();
127 server_o["name"] = picojson::value(std::string(server_name));
128 // active by default in CAPI
129 server_o["state"] = picojson::value(std::string("ACTIVE"));
131 servers->push_back(server);
136 PlatformResult MediaControllerClient::GetLatestServerInfo(picojson::value* server_info) {
140 char* name = nullptr;
144 mc_server_state_e state;
145 ret = mc_client_get_latest_server_info(handle_, &name, &state);
146 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
147 return LogAndCreateResult(
148 ErrorCode::UNKNOWN_ERR, "Error getting latest server info",
149 ("mc_client_get_latest_server_info() error: %d, message: %s", ret, get_error_message(ret)));
153 LoggerD("No active server available");
154 return PlatformResult(ErrorCode::NO_ERROR);
157 std::string state_str;
158 PlatformResult result = Types::PlatformEnumToString(Types::kMediaControllerServerState,
159 static_cast<int>(state), &state_str);
161 LoggerE("PlatformEnumToString failed, error: %s", result.message().c_str());
165 *server_info = picojson::value(picojson::object());
166 picojson::object& obj = server_info->get<picojson::object>();
167 obj["name"] = picojson::value(std::string(name));
168 obj["state"] = picojson::value(state_str);
170 return PlatformResult(ErrorCode::NO_ERROR);
173 PlatformResult MediaControllerClient::GetPlaybackInfo(const std::string& server_name,
174 picojson::object* playback_info) {
178 mc_playback_h playback_h;
179 ret = mc_client_get_server_playback_info(handle_, server_name.c_str(), &playback_h);
180 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
181 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error getting playback info",
182 ("mc_client_get_server_playback_info() error: %d, message: %s", ret,
183 get_error_message(ret)));
187 mc_client_destroy_playback(playback_h);
192 PlatformResult result = Types::ConvertPlaybackState(playback_h, &state);
194 LoggerE("ConvertPlaybackState failed, error: %s", result.message().c_str());
200 result = Types::ConvertPlaybackPosition(playback_h, &position);
202 LoggerE("ConvertPlaybackPosition failed, error: %s", result.message().c_str());
206 // content age rating
208 result = Types::ConvertContentAgeRating(playback_h, &rating);
210 LoggerE("ConvertContentAgeRating failed, error: %s", result.message().c_str());
215 mc_shuffle_mode_e shuffle;
216 ret = mc_client_get_server_shuffle_mode(handle_, server_name.c_str(), &shuffle);
217 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
218 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error getting shuffle mode",
219 ("mc_client_get_server_shuffle_mode() error: %d, message: %s", ret,
220 get_error_message(ret)));
224 mc_repeat_mode_e repeat;
225 ret = mc_client_get_server_repeat_mode(handle_, server_name.c_str(), &repeat);
226 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
227 return LogAndCreateResult(
228 ErrorCode::UNKNOWN_ERR, "Error getting repeat mode",
229 ("mc_client_get_server_repeat_mode() error: %d, message: %s", ret, get_error_message(ret)));
233 picojson::value metadata = picojson::value(picojson::object());
234 result = GetMetadata(server_name, &metadata.get<picojson::object>());
239 // fill return object
240 (*playback_info)["state"] = picojson::value(state);
241 (*playback_info)["position"] = picojson::value(position);
242 (*playback_info)["ageRating"] = picojson::value(rating);
243 (*playback_info)["shuffleMode"] = picojson::value(shuffle == MC_SHUFFLE_MODE_ON);
244 (*playback_info)["repeatMode"] = picojson::value(repeat == MC_REPEAT_MODE_ON);
245 (*playback_info)["metadata"] = metadata;
247 return PlatformResult(ErrorCode::NO_ERROR);
250 PlatformResult MediaControllerClient::GetMetadata(const std::string& server_name,
251 picojson::object* metadata) {
255 mc_metadata_h metadata_h = nullptr;
256 ret = mc_client_get_server_metadata(handle_, server_name.c_str(), &metadata_h);
257 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
258 return LogAndCreateResult(
259 ErrorCode::UNKNOWN_ERR, "Error getting server metadata",
260 ("mc_client_get_server_metadata() error: %d, message: %s", ret, get_error_message(ret)));
264 mc_metadata_destroy(metadata_h);
267 PlatformResult result = Types::ConvertMetadata(metadata_h, metadata);
272 return PlatformResult(ErrorCode::NO_ERROR);
275 PlatformResult MediaControllerClient::SetServerStatusChangeListener(const JsonCallback& callback) {
278 int ret = mc_client_set_server_updated_cb(handle_, OnServerStatusUpdate, this);
279 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
280 return LogAndCreateResult(
281 ErrorCode::UNKNOWN_ERR, "Unable to set server status listener",
282 ("mc_client_set_server_updated_cb() error: %d, message: %s", ret, get_error_message(ret)));
285 server_status_listener_ = callback;
287 return PlatformResult(ErrorCode::NO_ERROR);
290 PlatformResult MediaControllerClient::UnsetServerStatusChangeListener() {
292 int ret = mc_client_unset_server_updated_cb(handle_);
293 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
294 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to unset server status listener",
295 ("mc_client_unset_server_updated_cb() error: %d, message: %s", ret,
296 get_error_message(ret)));
298 server_status_listener_ = nullptr;
299 return PlatformResult(ErrorCode::NO_ERROR);
302 void MediaControllerClient::OnServerStatusUpdate(const char* server_name, mc_server_state_e state,
305 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
308 std::string state_str;
309 PlatformResult result = Types::PlatformEnumToString(Types::kMediaControllerServerState,
310 static_cast<int>(state), &state_str);
312 LoggerE("PlatformEnumToString failed, error: %s", result.message().c_str());
316 picojson::value data = picojson::value(picojson::object());
317 picojson::object& data_o = data.get<picojson::object>();
319 data_o["state"] = picojson::value(state_str);
320 data_o["name"] = picojson::value(server_name);
322 client->server_status_listener_(&data);
325 PlatformResult MediaControllerClient::SetPlaybackInfoListener(const JsonCallback& callback) {
327 int failed_setter = 0;
329 // Lambda function used to clean all set listeners (in case of failure of
330 // SetPlaybackInfoListener method).
331 // The purpose of this lambda is to unset as many setters as we can in case of failure.
333 int (*unsetters[])(mc_client_h) = {
334 mc_client_unset_playback_updated_cb, mc_client_unset_shuffle_mode_updated_cb,
335 mc_client_unset_repeat_mode_updated_cb,
336 /*mc_client_unset_metadata_updated_cb the last unsetter will never be used*/};
338 // This loop is no-op in case of success.
339 for (int i = 0; i < failed_setter; ++i) {
340 auto ret = unsetters[i](handle_);
341 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
342 LoggerE("Fail (%d) returned by the [%d] unsetter", ret, i);
347 int ret = mc_client_set_playback_updated_cb(handle_, OnPlaybackUpdate, this);
348 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
349 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register playback listener",
350 ("mc_client_set_playback_updated_cb() error: %d, message: %s", ret,
351 get_error_message(ret)));
354 ret = mc_client_set_shuffle_mode_updated_cb(handle_, OnShuffleModeUpdate, this);
355 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
357 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register shuffle mode listener",
358 ("mc_client_set_shuffle_mode_updated_cb() error: %d, message: %s",
359 ret, get_error_message(ret)));
362 ret = mc_client_set_repeat_mode_updated_cb(handle_, OnRepeatModeUpdate, this);
363 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
365 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register repeat mode listener",
366 ("mc_client_set_repeat_mode_updated_cb() error: %d, message: %s", ret,
367 get_error_message(ret)));
370 ret = mc_client_set_metadata_updated_cb(handle_, OnMetadataUpdate, this);
371 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
373 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to register metadata listener",
374 ("mc_client_set_metadata_updated_cb() error: %d, message: %s", ret,
375 get_error_message(ret)));
378 playback_info_listener_ = callback;
380 return PlatformResult(ErrorCode::NO_ERROR);
383 PlatformResult MediaControllerClient::UnsetPlaybackInfoListener() {
385 // Even though if one of below functions fails, let's try to unset as much listeners as we can.
386 // In the Javascript layer, the removePlaybackInfoChangeListener() method always succeeds, so we
387 // do not need to catch the returned value.
389 mc_client_unset_playback_updated_cb(handle_);
390 mc_client_unset_shuffle_mode_updated_cb(handle_);
391 mc_client_unset_repeat_mode_updated_cb(handle_);
392 mc_client_unset_metadata_updated_cb(handle_);
394 playback_info_listener_ = nullptr;
396 return PlatformResult(ErrorCode::NO_ERROR);
399 void MediaControllerClient::OnPlaybackUpdate(const char* server_name, mc_playback_h playback,
402 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
406 PlatformResult result = Types::ConvertPlaybackState(playback, &state);
408 LoggerE("ConvertPlaybackState failed, error: %s", result.message().c_str());
414 result = Types::ConvertPlaybackPosition(playback, &position);
416 LoggerE("ConvertPlaybackPosition failed, error: %s", result.message().c_str());
420 picojson::value data = picojson::value(picojson::object());
421 picojson::object& data_o = data.get<picojson::object>();
423 data_o["action"] = picojson::value(std::string("onplaybackchanged"));
424 data_o["state"] = picojson::value(state);
425 data_o["position"] = picojson::value(position);
426 data_o["name"] = picojson::value(server_name);
428 client->playback_info_listener_(&data);
431 void MediaControllerClient::OnShuffleModeUpdate(const char* server_name, mc_shuffle_mode_e mode,
434 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
436 picojson::value data = picojson::value(picojson::object());
437 picojson::object& data_o = data.get<picojson::object>();
439 data_o["action"] = picojson::value(std::string("onshufflemodechanged"));
440 data_o["mode"] = picojson::value(mode == MC_SHUFFLE_MODE_ON);
441 data_o["name"] = picojson::value(server_name);
443 client->playback_info_listener_(&data);
446 void MediaControllerClient::OnRepeatModeUpdate(const char* server_name, mc_repeat_mode_e mode,
449 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
451 picojson::value data = picojson::value(picojson::object());
452 picojson::object& data_o = data.get<picojson::object>();
454 data_o["name"] = picojson::value(server_name);
455 if (MC_REPEAT_MODE_ONE_MEDIA != mode) {
456 // The onrepeatmodechanged event may be reported only with mode equal to true/false. The 3rd
457 // mode is not supported by this event.
458 common::tools::PrintDeprecationWarningFor("onrepeatmodechanged", "onrepeatstatechanged");
459 data_o["action"] = picojson::value(std::string("onrepeatmodechanged"));
460 data_o["mode"] = picojson::value(mode == MC_REPEAT_MODE_ON);
461 client->playback_info_listener_(&data);
464 PlatformResult result = Types::PlatformEnumToString(Types::kMediaControllerRepeatState,
465 static_cast<int>(mode), &state);
467 LoggerE("PlatformEnumToString failed, error: %s", result.message().c_str());
470 data_o["action"] = picojson::value(std::string("onrepeatstatechanged"));
471 data_o["state"] = picojson::value(state);
473 client->playback_info_listener_(&data);
476 void MediaControllerClient::OnMetadataUpdate(const char* server_name, mc_metadata_h metadata_h,
479 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
481 picojson::value data = picojson::value(picojson::object());
482 picojson::object& data_o = data.get<picojson::object>();
484 picojson::value metadata = picojson::value(picojson::object());
485 PlatformResult result = Types::ConvertMetadata(metadata_h, &metadata.get<picojson::object>());
487 LoggerE("ConvertMetadata failed, error: %s", result.message().c_str());
491 data_o["action"] = picojson::value(std::string("onmetadatachanged"));
492 data_o["metadata"] = metadata;
493 data_o["name"] = picojson::value(server_name);
495 client->playback_info_listener_(&data);
498 PlatformResult MediaControllerClient::SendCommand(const std::string& server_name,
499 const std::string& command,
500 const picojson::value& data,
501 const JsonCallback& reply_cb, char** request_id) {
503 bundle* bundle = bundle_create();
509 ret = bundle_add(bundle, "data", data.serialize().c_str());
510 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
511 return LogAndCreateResult(
512 ErrorCode::UNKNOWN_ERR, "Unable to add data to bundle",
513 ("bundle_add(data) error: %d, message: %s", ret, get_error_message(ret)));
517 mc_client_send_custom_cmd(handle_, server_name.c_str(), command.c_str(), bundle, request_id);
518 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
519 return LogAndCreateResult(
520 ErrorCode::UNKNOWN_ERR, "Error sending custom command",
521 ("mc_client_send_custom_cmd() error: %d, message: %s", ret, get_error_message(ret)));
524 command_reply_callback_ = reply_cb;
526 return PlatformResult(ErrorCode::NO_ERROR);
529 void MediaControllerClient::OnCommandReply(const char* server_name, const char* request_id,
530 int result_code, bundle* bundle, void* user_data) {
532 MediaControllerClient* client = static_cast<MediaControllerClient*>(user_data);
534 picojson::value out = picojson::value(picojson::object());
535 picojson::object& out_o = out.get<picojson::object>();
536 picojson::value reply = picojson::value(picojson::object());
537 picojson::object& reply_o = reply.get<picojson::object>();
540 char* data_str = nullptr;
545 ret = bundle_get_str(bundle, "data", &data_str);
546 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
547 LoggerE("bundle_get_str(data) failed, error: %d", ret);
549 client->command_reply_callback_(&out);
553 picojson::value data;
555 picojson::parse(data, data_str, data_str + strlen(data_str), &err);
557 LoggerE("Failed to parse bundle data: %s", err.c_str());
559 client->command_reply_callback_(&out);
562 reply_o["data"] = data;
563 reply_o["name"] = picojson::value(server_name);
565 if (nullptr == request_id) {
566 LoggerE("Request id is null.");
568 client->command_reply_callback_(&out);
571 out_o["requestId"] = picojson::value(std::string(request_id));
573 ReportSuccess(reply, out_o);
574 client->command_reply_callback_(&out);
577 PlatformResult MediaControllerClient::SendPlaybackState(const std::string& server_name,
578 const std::string& state) {
581 // In Native API, since Tizen 5.0 an action instead of a state is sent to change the state of a
582 // server. In Web API the names were not refactored.
583 PlatformResult result =
584 Types::StringToPlatformEnum(Types::kMediaControllerPlaybackAction, state, &state_e);
589 /* TODO: Prepare an ACR and propose use case for request_id.
590 char* request_id = nullptr;
595 ret = mc_client_send_playback_action_cmd(handle_, server_name.c_str(),
596 static_cast<mc_playback_action_e>(state_e),
597 /*&request_id*/ nullptr);
598 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
599 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error sending playback state",
600 ("mc_client_send_playback_action_cmd() error: %d, message: %s", ret,
601 get_error_message(ret)));
604 return PlatformResult(ErrorCode::NO_ERROR);
607 PlatformResult MediaControllerClient::SendPlaybackPosition(const std::string& server_name,
610 /* TODO: Prepare an ACR and propose use case for request_id.
611 char* request_id = nullptr;
615 int ret = mc_client_send_playback_position_cmd(handle_, server_name.c_str(),
616 static_cast<unsigned long long>(position),
617 /*&request_id*/ nullptr);
618 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
619 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error sending playback position",
620 ("mc_client_send_playback_position_cmd() error: %d, message: %s", ret,
621 get_error_message(ret)));
624 return PlatformResult(ErrorCode::NO_ERROR);
627 PlatformResult MediaControllerClient::SendShuffleMode(const std::string& server_name, bool mode) {
629 /* TODO: Prepare an ACR and propose use case for request_id.
630 char* request_id = nullptr;
634 int ret = mc_client_send_shuffle_mode_cmd(handle_, server_name.c_str(),
635 mode ? MC_SHUFFLE_MODE_ON : MC_SHUFFLE_MODE_OFF,
636 /*&request_id*/ nullptr);
637 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
638 return LogAndCreateResult(
639 ErrorCode::UNKNOWN_ERR, "Error sending shuffle mode",
640 ("mc_client_send_shuffle_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
643 return PlatformResult(ErrorCode::NO_ERROR);
646 PlatformResult MediaControllerClient::SendRepeatMode(const std::string& server_name, bool mode) {
648 /* TODO: Prepare an ACR and propose use case for request_id.
649 char* request_id = nullptr;
653 int ret = mc_client_send_repeat_mode_cmd(handle_, server_name.c_str(),
654 mode ? MC_REPEAT_MODE_ON : MC_REPEAT_MODE_OFF,
655 /*&request_id*/ nullptr);
656 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
657 return LogAndCreateResult(
658 ErrorCode::UNKNOWN_ERR, "Error sending repeat mode",
659 ("mc_client_send_repeat_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
662 return PlatformResult(ErrorCode::NO_ERROR);
665 PlatformResult MediaControllerClient::SendRepeatState(const std::string& server_name,
666 const std::string& state) {
668 /* TODO: Prepare an ACR and propose use case for request_id.
669 char* request_id = nullptr;
674 PlatformResult result =
675 Types::StringToPlatformEnum(Types::kMediaControllerRepeatState, state, &state_e);
679 int ret = mc_client_send_repeat_mode_cmd(handle_, server_name.c_str(),
680 static_cast<mc_repeat_mode_e>(state_e),
681 /*&request_id*/ nullptr);
682 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
683 return LogAndCreateResult(
684 ErrorCode::UNKNOWN_ERR, "Error sending repeat state",
685 ("mc_client_send_repeat_mode_cmd() error: %d, message: %s", ret, get_error_message(ret)));
688 return PlatformResult(ErrorCode::NO_ERROR);
691 PlatformResult MediaControllerClient::SendPlaybackItem(const std::string& name,
692 const std::string& playlist_name,
693 const std::string& index,
694 const std::string& state, double position) {
698 // In Native API, since Tizen 5.0 an action instead of a state is sent to change the state of a
699 // server. In Web API the names were not refactored.
700 PlatformResult result =
701 Types::StringToPlatformEnum(Types::kMediaControllerPlaybackAction, state, &state_e);
707 int ret = mc_client_send_playlist_cmd(handle_, name.c_str(), playlist_name.c_str(), index.c_str(),
708 static_cast<mc_playback_action_e>(state_e),
709 static_cast<unsigned long long>(position), nullptr);
711 if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
712 return LogAndCreateResult(
713 ErrorCode::UNKNOWN_ERR, "Error sending playlist item",
714 ("mc_client_send_playlist_cmd() error: %d, message: %s", ret, get_error_message(ret)));
717 return PlatformResult(ErrorCode::NO_ERROR);
720 } // namespace mediacontroller
721 } // namespace extension