],
'sources': [
'mediacontroller_api.js',
+ 'mediacontroller_client.cc',
+ 'mediacontroller_client.h',
'mediacontroller_extension.cc',
'mediacontroller_extension.h',
'mediacontroller_instance.cc',
'mediacontroller_instance.h',
+ 'mediacontroller_types.cc',
+ 'mediacontroller_types.h',
],
'conditions': [
['tizen == 1', {
--- /dev/null
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mediacontroller/mediacontroller_client.h"
+
+#include "common/logger.h"
+#include "common/scope_exit.h"
+
+#include "mediacontroller/mediacontroller_types.h"
+
+namespace extension {
+namespace mediacontroller {
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+MediaControllerClient::MediaControllerClient() : handle_(nullptr) {
+}
+
+MediaControllerClient::~MediaControllerClient() {
+ LOGGER(DEBUG) << "entered";
+
+ if (handle_) {
+ int ret = mc_client_destroy(handle_);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ LOGGER(ERROR) << "Unable to destroy media controller client";
+ }
+ }
+}
+
+PlatformResult MediaControllerClient::Init() {
+ PlatformResult result = PlatformResult(ErrorCode::NO_ERROR);
+
+ int ret = mc_client_create(&handle_);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ LOGGER(ERROR) << "Unable to create media controller client, error: " << ret;
+ result = PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Unable to create media controller client");
+ }
+
+ return result;
+}
+
+PlatformResult MediaControllerClient::FindServers(picojson::array* servers) {
+ LOGGER(DEBUG) << "entered";
+
+ int ret;
+
+ ret = mc_client_foreach_server(handle_, FindServersCallback, servers);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ LOGGER(ERROR) << "Unable to fetch active servers, error: " << ret;
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Unable to create media controller client");
+ }
+
+ // check latest server state - if exist
+ picojson::value latest_server = picojson::value();
+ PlatformResult result = GetLatestServerInfo(&latest_server);
+ if (!result) {
+ LOGGER(ERROR) << "GetLatestServerInfo failed, error: " << result.message();
+ return result;
+ }
+
+ if (latest_server.is<picojson::null>()) {
+ LOGGER(DEBUG) << "No latest server available";
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ const std::string& latest_name = latest_server.get("name").get<std::string>();
+
+ // update current server state in list
+ for (picojson::array::iterator it; it != servers->end(); ++it) {
+ picojson::object& server = it->get<picojson::object>();
+ if (it->get("name").get<std::string>() == latest_name) {
+ server["state"] = latest_server.get("state");
+ break;
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+bool MediaControllerClient::FindServersCallback(const char* server_name,
+ void* user_data) {
+ LOGGER(DEBUG) << "entered";
+
+ picojson::array* servers = static_cast<picojson::array*>(user_data);
+
+ picojson::value server = picojson::value(picojson::object());
+ picojson::object& server_o = server.get<picojson::object>();
+ server_o["name"] = picojson::value(std::string(server_name));
+ // active by default in CAPI
+ server_o["state"] = picojson::value(std::string("ACTIVE"));
+
+ servers->push_back(server);
+
+ return true;
+}
+
+PlatformResult MediaControllerClient::GetLatestServerInfo(
+ picojson::value* server_info) {
+
+ int ret;
+
+ char* name;
+ mc_server_state_e state;
+ ret = mc_client_get_latest_server_info(handle_, &name, &state);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ LOGGER(ERROR) << "mc_client_get_latest_server_info failed, error: " << ret;
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "Error getting latest server info");
+ }
+
+ if (NULL == name) {
+ LOGGER(DEBUG) << "No active server available";
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ SCOPE_EXIT {
+ free(name);
+ };
+
+ std::string state_str;
+ PlatformResult result = Types::PlatformEnumToString(
+ Types::kMediaControllerServerState, static_cast<int>(state), &state_str);
+ if (!result) {
+ LOGGER(ERROR) << "PlatformEnumToString failed, error: " << result.message();
+ return result;
+ }
+
+ *server_info = picojson::value(picojson::object());
+ picojson::object& obj = server_info->get<picojson::object>();
+ obj["name"] = picojson::value(std::string(name));
+ obj["state"] = picojson::value(state_str);
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+} // namespace mediacontroller
+} // namespace extension
--- /dev/null
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIACONTROLLER_MEDIACONTROLLER_CLIENT_H_
+#define MEDIACONTROLLER_MEDIACONTROLLER_CLIENT_H_
+
+#include <media_controller_client.h>
+#include <string>
+
+#include "common/platform_result.h"
+
+namespace extension {
+namespace mediacontroller {
+
+class MediaControllerClient {
+ public:
+ MediaControllerClient();
+ virtual ~MediaControllerClient();
+
+ common::PlatformResult Init();
+ common::PlatformResult FindServers(picojson::array* servers);
+ common::PlatformResult GetLatestServerInfo(picojson::value* server_info);
+
+ private:
+ mc_client_h handle_;
+
+ static bool FindServersCallback(const char* server_name, void* user_data);
+};
+
+} // namespace mediacontroller
+} // namespace extension
+
+#endif // MEDIACONTROLLER_MEDIACONTROLLER_CLIENT_H_
#include "common/logger.h"
#include "common/picojson.h"
#include "common/platform_result.h"
+#include "common/task-queue.h"
namespace extension {
namespace mediacontroller {
namespace {
// The privileges required in MediaController API
const std::string kPrivilegeMediaControllerClient =
- "http://tizen.org/privilege/mediacontroller.client";
+ "http://tizen.org/privilege/mediacontroller.write";
const std::string kPrivilegeMediaControllerServer =
- "http://tizen.org/privilege/mediacontroller.server";
+ "http://tizen.org/privilege/mediacontroller.read";
} // namespace
-using common::PlatformResult;
using common::ErrorCode;
+using common::PlatformResult;
+using common::TaskQueue;
MediaControllerInstance::MediaControllerInstance() {
using namespace std::placeholders;
const picojson::value& args,
picojson::object& out) {
- // implement it
+ if (client_) {
+ ReportSuccess(out);
+ return;
+ }
- // if success
- // ReportSuccess(out);
- // if error
- // ReportError(out);
+ // TODO(r.galka) check privileges
+
+ client_ = std::make_shared<MediaControllerClient>();
+ const PlatformResult& result = client_->Init();
+ if (!result) {
+ client_.reset();
+ ReportError(result, &out);
+ }
+
+ ReportSuccess(out);
}
void MediaControllerInstance::MediaControllerClientFindServers(
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)
- int callbackId = static_cast<int>(args.get("callbackId").get<double>());
+ auto search = [this, args]() -> void {
+ LOGGER(DEBUG) << "entered";
- // implement it
+ picojson::value response = picojson::value(picojson::object());
+ picojson::object& response_obj = response.get<picojson::object>();
- // call ReplyAsync in later (Asynchronously)
+ picojson::value servers = picojson::value(picojson::array());
+ PlatformResult result = client_->FindServers(
+ &servers.get<picojson::array>());
- // if success
- // ReportSuccess(out);
- // if error
- // ReportError(out);
+ response_obj["callbackId"] = args.get("callbackId");
+ if (result) {
+ ReportSuccess(servers, response_obj);
+ } else {
+ ReportError(result, &response_obj);
+ }
+
+ PostMessage(response.serialize().c_str());
+ };
+
+ TaskQueue::GetInstance().Async(search);
+
+ ReportSuccess(out);
}
void MediaControllerInstance::MediaControllerClientGetLatestServerInfo(
const picojson::value& args,
picojson::object& out) {
- // implement it
+ if (!client_) {
+ ReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR,
+ "Client not initialized."), &out);
+ return;
+ }
- // if success
- // ReportSuccess(out);
- // if error
- // ReportError(out);
+ picojson::value server_info = picojson::value();
+ PlatformResult result = client_->GetLatestServerInfo(&server_info);
+ if (!result) {
+ ReportError(result, &out);
+ return;
+ }
+
+ ReportSuccess(server_info, out);
}
void MediaControllerInstance::MediaControllerServerInfoSendPlaybackState(
#ifndef MEDIACONTROLLER_MEDIACONTROLLER_INSTANCE_H_
#define MEDIACONTROLLER_MEDIACONTROLLER_INSTANCE_H_
+#include <memory>
+
#include "common/extension.h"
+#include "mediacontroller/mediacontroller_client.h"
+
namespace extension {
namespace mediacontroller {
void MediaControllerServerInfoRemoveServerStatusChangeListener(const picojson::value& args, picojson::object& out);
void MediaControllerServerInfoAddPlaybackInfoChangeListener(const picojson::value& args, picojson::object& out);
void MediaControllerServerInfoRemovePlaybackInfoChangeListener(const picojson::value& args, picojson::object& out);
+
+ std::shared_ptr<MediaControllerClient> client_;
};
} // namespace mediacontroller
--- /dev/null
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "mediacontroller/mediacontroller_types.h"
+
+#include "common/platform_result.h"
+
+namespace extension {
+namespace mediacontroller {
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+const std::string Types::kMediaControllerServerState
+ = "MediaControllerServerState";
+const std::string Types::kMediaControllerPlaybackState
+ = "MediaControllerPlaybackState";
+const std::string Types::kMediaControllerMetadataAttribute
+ = "MediaControllerMetadataAttribute";
+
+const PlatformEnumMap Types::platform_enum_map_ = {
+ {kMediaControllerServerState, {
+ {"ACTIVE", MC_SERVER_STATE_ACTIVATE},
+ {"INACTIVE", MC_SERVER_STATE_DEACTIVATE}}},
+ {kMediaControllerPlaybackState, {
+ {"PLAY", MEDIA_PLAYBACK_STATE_PLAYING},
+ {"PAUSE", MEDIA_PLAYBACK_STATE_PAUSED},
+ {"STOP", MEDIA_PLAYBACK_STATE_STOPPED},
+ {"NEXT", MEDIA_PLAYBACK_STATE_NEXT_FILE},
+ {"PREV", MEDIA_PLAYBACK_STATE_PREV_FILE},
+ {"FORWARD", MEDIA_PLAYBACK_STATE_FAST_FORWARD},
+ {"REWIND", MEDIA_PLAYBACK_STATE_REWIND}}},
+ {kMediaControllerMetadataAttribute, {
+ {"title", MEDIA_TITLE},
+ {"artist", MEDIA_ARTIST},
+ {"album", MEDIA_ALBUM},
+ {"author", MEDIA_AUTHOR},
+ {"genre", MEDIA_GENRE},
+ {"duration", MEDIA_DURATION},
+ {"date", MEDIA_DATE},
+ {"copyright", MEDIA_COPYRIGHT},
+ {"description", MEDIA_DESCRIPTION},
+ {"trackNum", MEDIA_TRACK_NUM},
+ {"picture", MEDIA_PICTURE}
+ }}
+};
+
+PlatformEnumReverseMap Types::platform_enum_reverse_map_ = {};
+
+PlatformResult Types::StringToPlatformEnum(const std::string& field,
+ const std::string& value,
+ int* platform_enum) {
+ auto iter = platform_enum_map_.find(field);
+ if (iter == platform_enum_map_.end()) {
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ std::string("Undefined platform enum type ") + field);
+ }
+
+ auto def = platform_enum_map_.at(field);
+ auto def_iter = def.find(value);
+ if (def_iter != def.end()) {
+ *platform_enum = def_iter->second;
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ std::string message =
+ "Platform enum value " + value + " not found for " + field;
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, message);
+}
+
+PlatformResult Types::PlatformEnumToString(const std::string& field,
+ int value,
+ std::string* platform_str) {
+ // TODO(r.galka) can be replaced by Boost.Bimap
+ if (platform_enum_reverse_map_.empty()) {
+ for (auto& def : platform_enum_map_) {
+ platform_enum_reverse_map_[def.first] = {};
+
+ for (auto& key : def.second) {
+ platform_enum_reverse_map_[def.first][key.second] = key.first;
+ }
+ }
+ }
+
+ auto it = platform_enum_reverse_map_.find(field);
+ if (it == platform_enum_reverse_map_.end()) {
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ std::string("Undefined platform enum type ") + field);
+ }
+
+ auto def = platform_enum_reverse_map_.at(field);
+ auto def_it = def.find(value);
+ if (def_it != def.end()) {
+ *platform_str = def_it->second;
+ return PlatformResult(ErrorCode::NO_ERROR);
+ }
+
+ std::string message = "Platform enum value " + std::to_string(value) +
+ " not found for " + field;
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, message);
+}
+
+} // namespace mediacontroller
+} // namespace extension
--- /dev/null
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIACONTROLLER_MEDIACONTROLLER_TYPES_H_
+#define MEDIACONTROLLER_MEDIACONTROLLER_TYPES_H_
+
+#include <map>
+#include <media_controller_type.h>
+#include <string>
+
+#include "common/platform_result.h"
+
+namespace extension {
+namespace mediacontroller {
+
+typedef std::map<std::string, std::map<std::string, int>> PlatformEnumMap;
+typedef std::map<std::string, std::map<int, std::string>> PlatformEnumReverseMap;
+
+class Types {
+ public:
+ static const std::string kMediaControllerServerState;
+ static const std::string kMediaControllerPlaybackState;
+ static const std::string kMediaControllerMetadataAttribute;
+
+ static common::PlatformResult StringToPlatformEnum(const std::string& type,
+ const std::string& value,
+ int* platform_enum);
+
+ static common::PlatformResult PlatformEnumToString(const std::string& field,
+ int value,
+ std::string* platform_str);
+
+ private:
+ static const PlatformEnumMap platform_enum_map_;
+ // TODO(r.galka) can be replaced by Boost.Bimap
+ static PlatformEnumReverseMap platform_enum_reverse_map_;
+};
+
+} // namespace mediacontroller
+} // namespace extension
+
+#endif // MEDIACONTROLLER_MEDIACONTROLLER_TYPES_H_