var types_ = validator_.Types;
var native_ = new xwalk.utils.NativeManager(extension);
+// TODO(r.galka) CAPI have no dedicated methods for position/shuffle/repeat change.
+// It should be updated when new version of CAPI will be available.
+// For now implementation is using internal commands.
+var internal_commands_ = {
+ sendPlaybackPosition: '__internal_sendPlaybackPosition',
+ sendShuffleMode: '__internal_sendShuffleMode',
+ sendRepeatMode: '__internal_sendRepeatMode'
+};
function ListenerManager(native, listenerName, handle) {
this.listeners = {};
this.handle = handle || function(msg, listener, watchId) {};
}
-ListenerManager.prototype.addListener = function(callback, data) {
+ListenerManager.prototype.addListener = function(callback) {
var id = this.nextId;
if (!this.nativeSet) {
this.native.addListener(this.listenerName, function(msg) {
}
}
}.bind(this));
+
this.nativeSet = true;
}
+
this.listeners[id] = callback;
- this.listeners[id].data = data || {};
++this.nextId;
return id;
};
var data = {
position: args.position
};
-
- var callback = function(result) {
- if (native_.isFailure(result)) {
- native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
- return;
- }
- native_.callIfPossible(args.successCallback);
- };
-
- native_.call('MediaControllerServerInfo_sendPlaybackPosition', data, callback);
+ this.sendCommand(internal_commands_.sendPlaybackPosition, data, successCallback, errorCallback);
};
MediaControllerServerInfo.prototype.sendShuffleMode = function(mode, successCallback, errorCallback) {
var data = {
mode: args.mode
};
-
- var callback = function(result) {
- if (native_.isFailure(result)) {
- native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
- return;
- }
- native_.callIfPossible(args.successCallback);
- };
-
- native_.call('MediaControllerServerInfo_sendShuffleMode', data, callback);
+ this.sendCommand(internal_commands_.sendShuffleMode, data, successCallback, errorCallback);
};
MediaControllerServerInfo.prototype.sendRepeatMode = function(mode, successCallback, errorCallback) {
var data = {
mode: args.mode
};
-
- var callback = function(result) {
- if (native_.isFailure(result)) {
- native_.callIfPossible(args.errorCallback, native_.getErrorObject(result));
- return;
- }
- native_.callIfPossible(args.successCallback);
- };
-
- native_.call('MediaControllerServerInfo_sendRepeatMode', data, callback);
+ this.sendCommand(internal_commands_.sendRepeatMode, data, successCallback, errorCallback);
};
MediaControllerServerInfo.prototype.sendCommand = function(command, data, successCallback, errorCallback) {
name: this.name
};
- var replyId = ReplyCommandListener.addListener(successCallback, nativeData);
+ var replyId = ReplyCommandListener.addListener(successCallback);
nativeData.replyId = replyId;
nativeData.listenerId = ReplyCommandListener.listenerName;
return PlatformResult(ErrorCode::NO_ERROR);
}
+PlatformResult MediaControllerClient::SendPlaybackPosition(
+ const std::string& server_name,
+ double position) {
+
+ // TODO(r.galka) implement when dedicated method will be available in CAPI
+
+ return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR);
+}
+
+PlatformResult MediaControllerClient::SendShuffleMode(
+ const std::string& server_name,
+ bool mode) {
+
+ // TODO(r.galka) implement when dedicated method will be available in CAPI
+
+ return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR);
+}
+
+PlatformResult MediaControllerClient::SendRepeatMode(
+ const std::string& server_name,
+ bool mode) {
+
+ // TODO(r.galka) implement when dedicated method will be available in CAPI
+
+ return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR);
+}
+
} // namespace mediacontroller
} // namespace extension
common::PlatformResult SendPlaybackState(const std::string& server_name,
const std::string& state);
+ common::PlatformResult SendPlaybackPosition(const std::string& server_name,
+ double position);
+ common::PlatformResult SendShuffleMode(const std::string& server_name,
+ bool mode);
+ common::PlatformResult SendRepeatMode(const std::string& server_name,
+ bool mode);
common::PlatformResult SendCommand(const std::string& server_name,
const std::string& command,
CHECK_EXIST(args, "listenerId", out)
JsonCallback callback = [this, args](picojson::value* data) -> void {
- LOGGER(DEBUG) << "entered";
- if (nullptr == data) {
+ if (!data) {
LOGGER(ERROR) << "No data passed to json callback";
return;
}
CHECK_EXIST(args, "state", out)
auto send = [this, args]() -> void {
- LOGGER(DEBUG) << "entered";
-
picojson::value response = picojson::value(picojson::object());
picojson::object& response_obj = response.get<picojson::object>();
response_obj["callbackId"] = args.get("callbackId");
void MediaControllerInstance::MediaControllerServerInfoSendPlaybackPosition(
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, "position", out)
- int callbackId = static_cast<int>(args.get("callbackId").get<double>());
- double position = args.get("position").get<double>();
+ auto send = [this, args]() -> void {
+ picojson::value response = picojson::value(picojson::object());
+ picojson::object& response_obj = response.get<picojson::object>();
+ response_obj["callbackId"] = args.get("callbackId");
- // implement it
+ PlatformResult result = client_->SendPlaybackPosition(
+ args.get("name").get<std::string>(),
+ args.get("position").get<double>());
- // call ReplyAsync in later (Asynchronously)
+ if (result) {
+ ReportSuccess(response_obj);
+ } else {
+ ReportError(result, &response_obj);
+ }
+
+ PostMessage(response.serialize().c_str());
+ };
+
+ TaskQueue::GetInstance().Async(send);
- // if success
- // ReportSuccess(out);
- // if error
- // ReportError(out);
+ ReportSuccess(out);
}
void MediaControllerInstance::MediaControllerServerInfoSendShuffleMode(
const picojson::value& args,
picojson::object& out) {
+
+ if (!client_) {
+ LOGGER(ERROR) << "Client not initialized.";
+ ReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR,
+ "Client not initialized."), &out);
+ return;
+ }
+
CHECK_EXIST(args, "callbackId", out)
+ CHECK_EXIST(args, "name", out)
CHECK_EXIST(args, "mode", out)
- int callbackId = static_cast<int>(args.get("callbackId").get<double>());
- bool mode = args.get("mode").get<bool>();
+ auto send = [this, args]() -> void {
+ picojson::value response = picojson::value(picojson::object());
+ picojson::object& response_obj = response.get<picojson::object>();
+ response_obj["callbackId"] = args.get("callbackId");
- // implement it
+ PlatformResult result = client_->SendShuffleMode(
+ args.get("name").get<std::string>(),
+ args.get("mode").get<bool>());
- // call ReplyAsync in later (Asynchronously)
+ if (result) {
+ ReportSuccess(response_obj);
+ } else {
+ ReportError(result, &response_obj);
+ }
- // if success
- // ReportSuccess(out);
- // if error
- // ReportError(out);
+ PostMessage(response.serialize().c_str());
+ };
+
+ TaskQueue::GetInstance().Async(send);
+
+ ReportSuccess(out);
}
void MediaControllerInstance::MediaControllerServerInfoSendRepeatMode(
const picojson::value& args,
picojson::object& out) {
+
+ if (!client_) {
+ LOGGER(ERROR) << "Client not initialized.";
+ ReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR,
+ "Client not initialized."), &out);
+ return;
+ }
+
CHECK_EXIST(args, "callbackId", out)
+ CHECK_EXIST(args, "name", out)
CHECK_EXIST(args, "mode", out)
- int callbackId = static_cast<int>(args.get("callbackId").get<double>());
- bool mode = args.get("mode").get<bool>();
+ auto send = [this, args]() -> void {
+ picojson::value response = picojson::value(picojson::object());
+ picojson::object& response_obj = response.get<picojson::object>();
+ response_obj["callbackId"] = args.get("callbackId");
+
+ PlatformResult result = client_->SendRepeatMode(
+ args.get("name").get<std::string>(),
+ args.get("mode").get<bool>());
- // implement it
+ if (result) {
+ ReportSuccess(response_obj);
+ } else {
+ ReportError(result, &response_obj);
+ }
- // call ReplyAsync in later (Asynchronously)
+ PostMessage(response.serialize().c_str());
+ };
- // if success
- // ReportSuccess(out);
- // if error
- // ReportError(out);
+ TaskQueue::GetInstance().Async(send);
+
+ ReportSuccess(out);
}
void MediaControllerInstance::MediaControllerServerInfoSendCommand(
namespace extension {
namespace mediacontroller {
+namespace {
+// The privileges that are required in Application API
+const std::string kInternalCommandSendPlaybackPosition
+ = "__internal_sendPlaybackPosition";
+const std::string kInternalCommandSendShuffleMode
+ = "__internal_sendShuffleMode";
+const std::string kInternalCommandSendRepeatMode
+ = "__internal_sendRepeatMode";
+} // namespace
+
using common::PlatformResult;
using common::ErrorCode;
const char* command,
bundle* bundle,
void* user_data) {
- LOGGER(DEBUG) << "entered";
MediaControllerServer* server = static_cast<MediaControllerServer*>(user_data);
+ int ret;
+ char* data_str = nullptr;
+ SCOPE_EXIT {
+ free(data_str);
+ };
+
+ ret = bundle_get_str(bundle, "data", &data_str);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ LOGGER(ERROR) << "bundle_get_str(data) failed, error: " << ret;
+ return;
+ }
+
+ picojson::value data;
+ std::string err;
+ picojson::parse(data, data_str, data_str + strlen(data_str), &err);
+ if (!err.empty()) {
+ LOGGER(ERROR) << "Failed to parse bundle data: " << err;
+ return;
+ }
+
+ // TODO(r.galka) CAPI have no dedicated methods for position/shuffle/repeat change.
+ // It should be updated when new version of CAPI will be available.
+ // For now implementation is using internal commands.
+ if (command == kInternalCommandSendPlaybackPosition) {
+ double position = data.get("position").get<double>();
+ server->SetPlaybackPosition(position);
+ server->OnPlaybackPositionCommand(client_name,
+ static_cast<unsigned long long>(position),
+ server);
+ return;
+ }
+ if (command == kInternalCommandSendShuffleMode) {
+ bool mode = data.get("mode").get<bool>();
+ server->SetShuffleMode(mode);
+ server->OnShuffleModeCommand(client_name,
+ mode ? SHUFFLE_MODE_ON : SHUFFLE_MODE_OFF,
+ server);
+ return;
+ }
+ if (command == kInternalCommandSendRepeatMode) {
+ bool mode = data.get("mode").get<bool>();
+ server->SetRepeatMode(mode);
+ server->OnRepeatModeCommand(client_name,
+ mode ? REPEAT_MODE_ON : REPEAT_MODE_OFF,
+ server);
+ return;
+ }
+
if (server->command_listener_) {
picojson::value request = picojson::value(picojson::object());
picojson::object& request_o = request.get<picojson::object>();
- int ret;
char* reply_id_str = nullptr;
- char* data_str = nullptr;
SCOPE_EXIT {
free(reply_id_str);
- free(data_str);
};
ret = bundle_get_str(bundle, "replyId", &reply_id_str);
return;
}
- ret = bundle_get_str(bundle, "data", &data_str);
- if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
- LOGGER(ERROR) << "bundle_get_str(data) failed, error: " << ret;
- return;
- }
-
- picojson::value data;
- std::string err;
- picojson::parse(data, data_str, data_str + strlen(data_str), &err);
- if (!err.empty()) {
- LOGGER(ERROR) << "Failed to parse bundle data: " << err;
- return;
- }
-
request_o["clientName"] = picojson::value(std::string(client_name));
request_o["command"] = picojson::value(std::string(command));
request_o["replyId"] = picojson::value(std::string(reply_id_str));
void MediaControllerServer::OnPlaybackStateCommand(const char* client_name,
mc_playback_states_e state_e,
void *user_data) {
- LOGGER(DEBUG) << "entered";
MediaControllerServer* server = static_cast<MediaControllerServer*>(user_data);
server->change_request_playback_info_listener_(&data);
}
+void MediaControllerServer::OnPlaybackPositionCommand(
+ const char* client_name,
+ unsigned long long position,
+ void* user_data) {
+
+ MediaControllerServer* server = static_cast<MediaControllerServer*>(user_data);
+
+ if (!server->change_request_playback_info_listener_) {
+ LOGGER(DEBUG) << "No change request playback info listener registered, skipping";
+ return;
+ }
+
+ picojson::value data = picojson::value(picojson::object());
+ picojson::object& data_o = data.get<picojson::object>();
+
+ data_o["action"] = picojson::value(std::string("onplaybackpositionrequest"));
+ data_o["position"] = picojson::value(static_cast<double>(position));
+
+ server->change_request_playback_info_listener_(&data);
+}
+
+void MediaControllerServer::OnShuffleModeCommand(const char* client_name,
+ mc_shuffle_mode_e mode,
+ void* user_data) {
+
+ MediaControllerServer* server = static_cast<MediaControllerServer*>(user_data);
+
+ if (!server->change_request_playback_info_listener_) {
+ LOGGER(DEBUG) << "No change request playback info listener registered, skipping";
+ return;
+ }
+
+ picojson::value data = picojson::value(picojson::object());
+ picojson::object& data_o = data.get<picojson::object>();
+
+ data_o["action"] = picojson::value(std::string("onshufflemoderequest"));
+ data_o["mode"] = picojson::value(mode == SHUFFLE_MODE_ON);
+
+ server->change_request_playback_info_listener_(&data);
+}
+
+void MediaControllerServer::OnRepeatModeCommand(const char* client_name,
+ mc_repeat_mode_e mode,
+ void* user_data) {
+
+ MediaControllerServer* server = static_cast<MediaControllerServer*>(user_data);
+
+ if (!server->change_request_playback_info_listener_) {
+ LOGGER(DEBUG) << "No change request playback info listener registered, skipping";
+ return;
+ }
+
+ picojson::value data = picojson::value(picojson::object());
+ picojson::object& data_o = data.get<picojson::object>();
+
+ data_o["action"] = picojson::value(std::string("onrepeatmoderequest"));
+ data_o["mode"] = picojson::value(mode == REPEAT_MODE_ON);
+
+ server->change_request_playback_info_listener_(&data);
+}
+
} // namespace mediacontroller
} // namespace extension
static void OnPlaybackStateCommand(const char* client_name,
mc_playback_states_e state_e,
void *user_data);
+ static void OnPlaybackPositionCommand(const char* client_name,
+ unsigned long long position,
+ void* user_data);
+ static void OnShuffleModeCommand(const char* client_name,
+ mc_shuffle_mode_e mode,
+ void* user_data);
+ static void OnRepeatModeCommand(const char* client_name,
+ mc_repeat_mode_e mode,
+ void* user_data);
+
static void OnCommandReceived(const char* client_name,
const char* command,
bundle* data,