From d3d3a52116788a8b961deb6e7cc1a82b7f655c99 Mon Sep 17 00:00:00 2001 From: Andrzej Popowski Date: Fri, 11 Nov 2016 15:44:55 +0900 Subject: [PATCH] [Convergence] - Functions return TizenResult and launchAppControl, start and stop implemented Change-Id: Ief1d4df70193ea98f342dce566d5af52d2834979 Signed-off-by: Andrzej Popowski --- src/convergence/convergence_api.js | 278 +++++--- src/convergence/convergence_instance.cc | 668 +++++++++--------- src/convergence/convergence_instance.h | 43 +- .../convergence_remote_app_control_service.cc | 338 +++++++-- .../convergence_remote_app_control_service.h | 11 +- src/convergence/convergence_utils.cc | 13 +- src/convergence/convergence_utils.h | 10 + 7 files changed, 830 insertions(+), 531 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index dd7be5c0..7cad8500 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -78,7 +78,7 @@ function getServiceConnectionStateName(connectionStateNumber) { return ConnectionState.CONNECTING; default: console.log('ERROR: Unknown connection state'); - return -1; // TODO throw exception + return 'UNKNOWN'; // TODO throw exception } } @@ -170,14 +170,15 @@ ConvergenceManager.prototype.startDiscovery = function(successCallback, // Start the discovery using Native API var result = native_.call('ConvergenceManager_startDiscovery', { - timeout: (args.timeout) ? args.timeout : 0 - }, function(result) { - if (native_.isFailure(result)) { - native_.callIfPossible(errorCallback, native_.getErrorObject(result)); - } - }); - if (native_.isFailure(result)) + timeout: (args.timeout) ? args.timeout : 0 + }, function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }); + if (native_.isFailure(result)) { throw native_.getErrorObject(result); + } }; ConvergenceManager.prototype.stopDiscovery = function() { @@ -233,6 +234,12 @@ native_.addListener('REMOTE_APP_CONTROL_SERVICE_LISTENER', function(result) { native_.callIfPossible(s._remoteAppControlCallback, result.payload); break; + case 'onStart': + native_.callIfPossible(s._startCallback, s); + break; + case 'onStop': + native_.callIfPossible(s._stopCallback, null); + break; default: console.log('Ignoring result type: [' + result_type + ']'); break; @@ -342,18 +349,96 @@ RemoteAppControlService.prototype.disconnect = function(successCallback, errorCa throw new WebAPIException('InvalidStateError', 'Service is not connected yet.'); } - var result = native_.callSync('RemoteAppControlService_disconnect', { - deviceId: this._deviceId - }); + var result = native_.call('RemoteAppControlService_disconnect', { + deviceId: this._deviceId + }, function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }); - if (native_.isFailure(result)) + if (native_.isFailure(result)) { throw native_.getErrorObject(result); - else + } else { connectionState = ConnectionState.DISCONNECTED; + } native_.callIfPossible(successCallback, this); }; +RemoteAppControlService.prototype.start = function(successCallback, errorCallback) { + var args = validator_.validateArgs(arguments, [{ + name: 'successCallback', + type: types_.FUNCTION, + optional: false, + nullable: false + }, { + name: 'errorCallback', + type: types_.FUNCTION, + optional: true, + nullable: true + }]); + +/* + if (this.serviceState == ConnectionState.CONNECTED) + throw new WebAPIException('InvalidStateError', 'Service is connected already.'); +*/ + + var lid = this._serviceId; + this._startCallback = successCallback; + convergenceServices[lid] = this; + + var callArgs = {}; + callArgs.reply = !!successCallback; + callArgs.deviceId = this._deviceId; + callArgs.curListenerId = lid; + + var callback = function(result) { + if (native.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }; + + var result = native_.call('RemoteAppControlService_start', callArgs, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + +RemoteAppControlService.prototype.stop = function(successCallback, errorCallback) { + var args = validator_.validateArgs(arguments, [{ + name: 'successCallback', + type: types_.FUNCTION, + optional: true, + nullable: true + }, { + name: 'errorCallback', + type: types_.FUNCTION, + optional: true, + nullable: true + }]); + + var lid = this._serviceId; + this._stopCallback = successCallback; + convergenceServices[lid] = this; + + var callArgs = {}; + callArgs.reply = !!successCallback; + callArgs.deviceId = this._deviceId; + callArgs.curListenerId = lid; + + var callback = function(result) { + if (native.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }; + + var result = native_.call('RemoteAppControlService_stop', callArgs, callback); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } +}; + RemoteAppControlService.prototype.launch = function(appId, successCallback, errorCallback) { console.log('Entered RemoteAppControlService.launch()'); var args = validator_.validateArgs(arguments, [ @@ -407,43 +492,52 @@ RemoteAppControlService.prototype.launch = function(appId, successCallback, erro throw native_.getErrorObject(result); }; -RemoteAppControlService.prototype.launchAppControl = function( - appControl, appId, successCallback, errorCallback) { - console.log('Entered RemoteAppControlService.launchAppControl()'); - var args = validator_.validateArgs(arguments, [ - { - name: 'appControl', - type: types_.PLATFORM_OBJECT, - values: tizen.ApplicationControl, - optional: false, - nullable:false - }, - { - name: 'appId', - type: types_.PLATFORM_OBJECT, - values: tizen.ApplicationId, - optional: true, - nullable: true - }, - { - name: 'successCallback', - type: types_.FUNCTION, - //values: RemoteAppControlCallback, - optional: true, - nullable: true - }, - { - name: 'errorCallback', - type: types_.FUNCTION, - //values: ErrorCallback, - optional: true, - nullable: true - } - ]); +RemoteAppControlService.prototype.launchAppControl = function() { + var args = validator_.validateArgs(arguments, [{ + name: 'appControl', + type: types_.PLATFORM_OBJECT, + values: tizen.ApplicationControl, + optional: false, + nullable:false + }, { + name: 'appId', + type: types_.PLATFORM_OBJECT, + values: tizen.ApplicationId, + optional: true, + nullable: true + }, { + name: 'successCallback', + type: types_.FUNCTION, + optional: true, + nullable: true + }, { + name: 'errorCallback', + type: types_.FUNCTION, + optional: true, + nullable: true + }]); + + var lid = this._serviceId; + this._remoteAppControlCallback = successCallback; + convergenceServices[lid] = this; + + var callArgs = {}; + callArgs.appControl = args.appControl; + callArgs.appId = args.appId ? appId : ""; + callArgs.reply = !!successCallback; + callArgs.deviceId = this._deviceId; + callArgs.curListenerId = lid; - // TODO Implement pls + var callback = function(result) { + if (native.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }; - return; // TODO remove when native layer is implemented + var result = native.call('RemoteAppControlService_launchAppControl', callArgs, callback); + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } }; function AppCommunicationService() { @@ -623,15 +717,17 @@ AppCommunicationService.prototype.start = function(channel, successCallback, err convergenceServices[lid] = this; var result = native_.call('AppCommunicationService_start', { - deviceId: this._deviceId, - curListenerId: lid, - channel_data: channel - }, function(result) { - if (native_.isFailure(result)) - native_.callIfPossible(errorCallback, native_.getErrorObject(result)); - }); - if (native_.isFailure(result)) + deviceId: this._deviceId, + curListenerId: lid, + channel_data: channel + }, function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }); + if (native_.isFailure(result)) { throw native_.getErrorObject(result); + } }; AppCommunicationService.prototype.stop = function(channel, successCallback, errorCallback) { @@ -672,15 +768,17 @@ AppCommunicationService.prototype.stop = function(channel, successCallback, erro } var result = native_.call('AppCommunicationService_stop', { - deviceId: this._deviceId, - curListenerId: lid, - channel_data: channel - }, function(result) { - if (native_.isFailure(result)) - native_.callIfPossible(errorCallback, native_.getErrorObject(result)); - }); - if (native_.isFailure(result)) + deviceId: this._deviceId, + curListenerId: lid, + channel_data: channel + }, function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }); + if (native_.isFailure(result)) { throw native_.getErrorObject(result); + } }; AppCommunicationService.prototype.send = function(channel, payload, successCallback, errorCallback) { @@ -725,16 +823,18 @@ AppCommunicationService.prototype.send = function(channel, payload, successCallb convergenceServices[lid] = this; var result = native_.call('AppCommunicationService_send', { - deviceId: this._deviceId, - curListenerId: lid, - channel_data: channel, - payload: payload - }, function(result) { - if (native_.isFailure(result)) - native_.callIfPossible(errorCallback, native_.getErrorObject(result)); - }); - if (native_.isFailure(result)) + deviceId: this._deviceId, + curListenerId: lid, + channel_data: channel, + payload: payload + }, function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }); + if (native_.isFailure(result)) { throw native_.getErrorObject(result); + } }; AppCommunicationService.prototype.setListener = function(listenerCallback) { @@ -836,14 +936,16 @@ AppCommunicationClientService.prototype.connect = function(successCallback, erro convergenceServices[lid] = this; var result = native_.call('AppCommunicationClientService_connect', { - deviceId: this._deviceId, - curListenerId: lid - }, function(result) { - if (native_.isFailure(result)) - native_.callIfPossible(errorCallback, native_.getErrorObject(result)); - }); - if (native_.isFailure(result)) + deviceId: this._deviceId, + curListenerId: lid + }, function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }); + if (native_.isFailure(result)) { throw native_.getErrorObject(result); + } }; AppCommunicationClientService.prototype.disconnect = function(successCallback, errorCallback) { @@ -868,14 +970,18 @@ AppCommunicationClientService.prototype.disconnect = function(successCallback, e if (this.serviceState != ConnectionState.CONNECTED) throw new WebAPIException('InvalidStateError', 'Service is not connected yet.'); - var result = native_.callSync('AppCommunicationClientService_disconnect', { - deviceId: this._deviceId - }); - - if (native_.isFailure(result)) + var result = native_.call('AppCommunicationClientService_disconnect', { + deviceId: this._deviceId + }, function(result) { + if (native_.isFailure(result)) { + native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } + }); + if (native_.isFailure(result)) { throw native_.getErrorObject(result); - else + } else { connectionState = ConnectionState.DISCONNECTED; + } native_.callIfPossible(successCallback, this); }; diff --git a/src/convergence/convergence_instance.cc b/src/convergence/convergence_instance.cc index 06e80953..51316fcf 100644 --- a/src/convergence/convergence_instance.cc +++ b/src/convergence/convergence_instance.cc @@ -18,12 +18,14 @@ #include #include +#include #include "convergence/convergence_manager.h" #include "convergence/convergence_remote_app_control_service.h" #include "convergence/convergence_app_communication_service.h" #include "convergence/convergence_channel_info.h" #include "convergence/convergence_payload.h" +#include "convergence/convergence_utils.h" #include "common/logger.h" #include "common/picojson.h" #include "common/task-queue.h" @@ -56,38 +58,36 @@ static const std::string kJSArgumentAppId = "appId"; static const std::string kJSArgumentReply = "reply"; static const std::string kJSArgumentTimeout = "timeout"; static const std::string kJSArgumentService = "service"; +static const std::string kJSArgumentAppControl = "appControl"; } // namespace using namespace common; ConvergenceInstance::ConvergenceInstance() { using namespace std::placeholders; - #define REGISTER_SYNC(c,x) \ - RegisterSyncHandler(c, std::bind(&ConvergenceInstance::x, this, _1, _2)); - REGISTER_SYNC("ConvergenceManager_stopDiscovery", - ConvergenceManagerStopDiscovery); +#define REGISTER_SYNC(c, x) \ + RegisterSyncHandler(c, std::bind(&ConvergenceInstance::x, this, _1)) + REGISTER_SYNC("ConvergenceManager_stopDiscovery", ConvergenceManagerStopDiscovery); REGISTER_SYNC("AppCommunicationService_setListener", AppCommunicationServiceSetListener); REGISTER_SYNC("AppCommunicationService_unsetListener", AppCommunicationServiceUnsetListener); - //REGISTER_SYNC("Service_createLocalService", ServiceCreateLocal); - #undef REGISTER_SYNC - #define REGISTER_ASYNC(c,x) \ - RegisterSyncHandler(c, std::bind(&ConvergenceInstance::x, this, _1, _2)); - REGISTER_ASYNC("ConvergenceManager_startDiscovery", - ConvergenceManagerStartDiscovery); - - REGISTER_ASYNC("RemoteAppControlService_connect", RemoteAppControlServiceConnect); - REGISTER_ASYNC("RemoteAppControlService_disconnect", RemoteAppControlServiceDisconnect); - REGISTER_ASYNC("RemoteAppControlService_launch", RemoteAppControlServiceLaunch); + REGISTER_SYNC("AppCommunicationServerService_constructLocal", AppCommunicationServerServiceConstructLocal); +#undef REGISTER_SYNC + #define REGISTER_ASYNC(c,x) \ + RegisterHandler(c, std::bind(&ConvergenceInstance::x, this, _1, _2)) + REGISTER_ASYNC("ConvergenceManager_startDiscovery", ConvergenceManagerStartDiscovery); + REGISTER_ASYNC("AppCommunicationClientService_connect", AppCommunicationClientServiceConnect); + REGISTER_ASYNC("AppCommunicationClientService_disconnect", AppCommunicationClientServiceDisconnect); REGISTER_ASYNC("AppCommunicationService_start", AppCommunicationServiceStart); REGISTER_ASYNC("AppCommunicationService_stop", AppCommunicationServiceStop); REGISTER_ASYNC("AppCommunicationService_send", AppCommunicationServiceSend); - - REGISTER_ASYNC("AppCommunicationServerService_constructLocal", AppCommunicationServerServiceConstructLocal); - - REGISTER_ASYNC("AppCommunicationClientService_connect", AppCommunicationClientServiceConnect); - REGISTER_ASYNC("AppCommunicationClientService_disconnect", AppCommunicationClientServiceDisconnect); + REGISTER_ASYNC("RemoteAppControlService_disconnect", RemoteAppControlServiceDisconnect); + REGISTER_ASYNC("RemoteAppControlService_connect", RemoteAppControlServiceConnect); + REGISTER_ASYNC("RemoteAppControlService_start", RemoteAppControlServiceStart); + REGISTER_ASYNC("RemoteAppControlService_stop", RemoteAppControlServiceStop); + REGISTER_ASYNC("RemoteAppControlService_launch", RemoteAppControlServiceLaunch); + REGISTER_ASYNC("RemoteAppControlService_launchAppControl", RemoteAppControlServiceLaunchAppControl); #undef REGISTER_ASYNC } @@ -143,533 +143,503 @@ void ConvergenceInstance::ReplyAsync(ConvergenceCallbacks callback_function_type PostMessage(result.serialize().c_str()); } -#define CHECK_EXIST(args, name, out) \ - if (!args.contains(name)) {\ - ReportError(TypeMismatchException(name" is required argument"), out);\ - return;\ - } - -void ConvergenceInstance::ConvergenceManagerStartDiscovery( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::ConvergenceManagerStartDiscovery(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); - CHECK_EXIST(args, "callbackId", out) - CHECK_EXIST(args, "timeout", out) + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); + CHECK_EXIST(args, kJSArgumentTimeout); + CHECK_EXIST(args, kJSCallbackId); - LoggerI("ARGS: %s", args.serialize().c_str()); - - auto start_discovery = - [this, args](const std::shared_ptr& result) { + auto start_discovery = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("start_discovery"); // Start the discovery procedure - ConvergenceManager::GetInstance(this).StartDiscovery( - static_cast(args.get(kJSArgumentTimeout).get())); - - picojson::object& object = result->get(); - object[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(object); + TizenResult result = ConvergenceManager::GetInstance(this).StartDiscovery( + static_cast(ConvergenceUtils::GetArg(args, kJSArgumentTimeout).get())); + this->Post(token, result); }; - auto start_discovery_result = - [this, args](const std::shared_ptr& result) { - ScopeLogger("start_discovery_result"); - result->get()[kJSCallbackId] = args.get(kJSCallbackId); - Instance::PostMessage(this, result->serialize().c_str()); - }; - - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; + std::thread(start_discovery, token).detach(); - TaskQueue::GetInstance().Queue( - start_discovery, - start_discovery_result, - data); - - ReportSuccess(out); + return common::TizenSuccess(); } -void ConvergenceInstance::ConvergenceManagerStopDiscovery( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::ConvergenceManagerStopDiscovery(const picojson::object& args) { ScopeLogger(); - /*CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out) - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out) - CHECK_PRIVILEGE_ACCESS(kPrivilegeWifiDirect, &out)*/ + /*CHECK_PRIVILEGE(kPrivilegeInternet) + CHECK_PRIVILEGE(kPrivilegeBluetooth) + CHECK_PRIVILEGE(kPrivilegeWifiDirect)*/ // Running the discovery stop procedure - ConvergenceManager::GetInstance(this).StopDiscovery(); - //out[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(out); + return ConvergenceManager::GetInstance(this).StopDiscovery(); } -void ConvergenceInstance::RemoteAppControlServiceConnect( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::RemoteAppControlServiceConnect(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); - CHECK_EXIST(args, "callbackId", out) + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSCurrentListenerId); - LoggerI("ARGS: %s", args.serialize().c_str()); + LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); - auto connect = - [this, args](const std::shared_ptr& result) { + auto connect = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("connect"); + TizenResult result = TizenSuccess(); + // Finding the service ConvergenceRemoteAppControlService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_REMOTE_APP_CONTROL)); if (!service) { - LoggerE("Can not find the service type = 1, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - //ReportSuccess(object); // TODO ReportError - return; + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service connect procedure + result = service->Connect(static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - // Running the service connect procedure - service->Connect(static_cast(args.get(kJSCurrentListenerId).get())); - - picojson::object& object = result->get(); - object[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(object); + this->Post(token, result); }; - auto connect_result = - [this, args](const std::shared_ptr& result) { - ScopeLogger("connect_result"); + std::thread(connect, token).detach(); - result->get()[kJSCallbackId] = args.get(kJSCallbackId); - Instance::PostMessage(this, result->serialize().c_str()); - }; + return TizenSuccess(); +} - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; +common::TizenResult ConvergenceInstance::RemoteAppControlServiceDisconnect(const picojson::object& args, + const common::AsyncToken& token) { + ScopeLogger(); + + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); - TaskQueue::GetInstance().Queue( - connect, - connect_result, - data); + //LoggerI("ARGS: %s", args.serialize().c_str()); - ReportSuccess(out); + auto disconnect = [this, args](const common::AsyncToken& token) -> void { + ScopeLogger("disconnect"); + + TizenResult result = TizenSuccess(); + + ConvergenceRemoteAppControlService *service = + static_cast( + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), + CONV_SERVICE_REMOTE_APP_CONTROL)); + if (!service) { + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + result = service->Disconnect(); + } + + this->Post(token, result); + }; + + std::thread(disconnect, token).detach(); + + return TizenSuccess(); } -void ConvergenceInstance::RemoteAppControlServiceDisconnect( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::RemoteAppControlServiceStart(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSArgumentReply); + CHECK_EXIST(args, kJSCurrentListenerId); - //LoggerI("ARGS: %s", args.serialize().c_str()); + LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); - auto disconnect = - [this, args](const std::shared_ptr& result) { - ScopeLogger("disconnect"); + auto start = [this, args](const common::AsyncToken& token) -> void { + ScopeLogger("start"); + + TizenResult result = TizenSuccess(); // Finding the service ConvergenceRemoteAppControlService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_REMOTE_APP_CONTROL)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 1, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service start procedure + result = service->Start(static_cast(ConvergenceUtils::GetArg(args, kJSArgumentReply).get()), + static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - // Running the service disconnect procedure - service->Disconnect(); - - picojson::object& object = result->get(); - ReportSuccess(object); + this->Post(token, result); }; - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; - - TaskQueue::GetInstance().Async( - disconnect, - data); + std::thread(start, token).detach(); - ReportSuccess(out); + return TizenSuccess(); } -void ConvergenceInstance::RemoteAppControlServiceLaunch( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::RemoteAppControlServiceStop(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); - CHECK_EXIST(args, "callbackId", out) + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeDataSharing, &out); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSArgumentReply); + CHECK_EXIST(args, kJSCurrentListenerId); - auto launch = [this, args](const std::shared_ptr& result) { - ScopeLogger("send"); + LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); + + auto stop = [this, args](const common::AsyncToken& token) -> void { + ScopeLogger("stop"); + + TizenResult result = TizenSuccess(); // Finding the service ConvergenceRemoteAppControlService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_REMOTE_APP_CONTROL)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 1, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service stop procedure + result = service->Stop(static_cast(ConvergenceUtils::GetArg(args, kJSArgumentReply).get()), + static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - // Running the service app control procedure - service->Launch( - args.get(kJSArgumentAppId).to_str().c_str(), - static_cast(args.get(kJSArgumentReply).get()), - static_cast(args.get(kJSCurrentListenerId).get())); - - picojson::object& object = result->get(); - object[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(object); + this->Post(token, result); }; - auto launch_result = - [this, args](const std::shared_ptr& result) { - ScopeLogger("send_result"); - result->get()[kJSCallbackId] = args.get(kJSCallbackId); - Instance::PostMessage(this, result->serialize().c_str()); + std::thread(stop, token).detach(); + + return TizenSuccess(); +} + +common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunch(const picojson::object& args, + const common::AsyncToken& token) { + ScopeLogger(); + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); + CHECK_PRIVILEGE(kPrivilegeDataSharing); + + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSArgumentAppId); + CHECK_EXIST(args, kJSArgumentReply); + CHECK_EXIST(args, kJSCurrentListenerId); + + auto launch = [this, args](const common::AsyncToken& token) -> void { + ScopeLogger("launch"); + + TizenResult result = TizenSuccess(); + + // Finding the service + ConvergenceRemoteAppControlService *service = + static_cast( + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), + CONV_SERVICE_REMOTE_APP_CONTROL)); + if (!service) { + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + result = service->Launch( + ConvergenceUtils::GetArg(args, kJSArgumentAppId).to_str().c_str(), + static_cast(ConvergenceUtils::GetArg(args, kJSArgumentReply).get()), + static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); + } + + this->Post(token, result); }; - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; + std::thread(launch, token).detach(); + + return TizenSuccess(); +} + +common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunchAppControl(const picojson::object& args, + const common::AsyncToken& token) { + ScopeLogger(); + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); + CHECK_PRIVILEGE(kPrivilegeDataSharing); + + CHECK_EXIST(args, kJSArgumentAppControl); + CHECK_EXIST(args, kJSArgumentAppId); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSArgumentReply); + CHECK_EXIST(args, kJSCurrentListenerId); + + auto launch_app_control = [this, args](const common::AsyncToken& token) -> void { + ScopeLogger("launch_app_control"); - TaskQueue::GetInstance().Queue( - launch, - launch_result, - data); + TizenResult result = TizenSuccess(); - ReportSuccess(out); + // Finding the service + ConvergenceRemoteAppControlService *service = + static_cast( + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), + CONV_SERVICE_REMOTE_APP_CONTROL)); + if (!service) { + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + result = service->LaunchAppControl(ConvergenceUtils::GetArg(args, kJSArgumentAppControl).get(), + ConvergenceUtils::GetArg(args, kJSArgumentAppId).to_str().c_str(), + ConvergenceUtils::GetArg(args, kJSArgumentReply).get(), + static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); + } + + this->Post(token, result); + }; + + std::thread(launch_app_control, token).detach(); + + return TizenSuccess(); } -void ConvergenceInstance::AppCommunicationServiceStart( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationServiceStart(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); - CHECK_EXIST(args, "callbackId", out) + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); + CHECK_PRIVILEGE(kPrivilegeDataSharing); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeDataSharing, &out); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSArgumentChannel); + CHECK_EXIST(args, kJSCurrentListenerId); - auto start = [this, args](const std::shared_ptr& result) { + auto start = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("start"); + TizenResult result = TizenSuccess(); + // Finding the service ConvergenceAppCommunicationService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 0, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service start procedure + result = service->Start(new ConvergenceChannel(ConvergenceUtils::GetArg(args, kJSArgumentChannel)), + static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - // Running the service start procedure - service->Start(new ConvergenceChannel(args.get(kJSArgumentChannel)), - static_cast(args.get(kJSCurrentListenerId).get())); - - picojson::object& object = result->get(); - object[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(object); + this->Post(token, result); }; - auto start_result = - [this, args](const std::shared_ptr& result) { - ScopeLogger("start_result"); - result->get()[kJSCallbackId] = args.get(kJSCallbackId); - Instance::PostMessage(this, result->serialize().c_str()); - }; - - auto data = std::shared_ptr{new picojson::value{picojson::object()}}; + std::thread(start, token).detach(); - TaskQueue::GetInstance().Queue( - start, - start_result, - data); - - ReportSuccess(out); + return TizenSuccess(); } -void ConvergenceInstance::AppCommunicationServiceSend( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationServiceSend(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); - CHECK_EXIST(args, "callbackId", out) + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); + CHECK_PRIVILEGE(kPrivilegeDataSharing); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeDataSharing, &out); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSArgumentChannel); + CHECK_EXIST(args, kJSArgumentPayload); + CHECK_EXIST(args, kJSCurrentListenerId); - auto send = [this, args](const std::shared_ptr& result) { + auto send = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("send"); + TizenResult result = TizenSuccess(); + // Finding the service ConvergenceAppCommunicationService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 0, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; - } + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service send procedure + result = service->Send(new ConvergenceChannel(ConvergenceUtils::GetArg(args, kJSArgumentChannel)), + new ConvergencePayloadArray(ConvergenceUtils::GetArg(args, kJSArgumentPayload)), + static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); - // Running the service send procedure - service->Send(new ConvergenceChannel(args.get(kJSArgumentChannel)), - new ConvergencePayloadArray(args.get(kJSArgumentPayload)), - static_cast(args.get(kJSCurrentListenerId).get())); - - picojson::object& object = result->get(); - object[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(object); - }; + } - auto send_result = - [this, args](const std::shared_ptr& result) { - ScopeLogger("send_result"); - result->get()[kJSCallbackId] = args.get(kJSCallbackId); - Instance::PostMessage(this, result->serialize().c_str()); + this->Post(token, result); }; - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; - - TaskQueue::GetInstance().Queue( - send, - send_result, - data); + std::thread(send, token).detach(); - ReportSuccess(out); + return TizenSuccess(); } -void ConvergenceInstance::AppCommunicationServiceStop( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationServiceStop(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); - CHECK_EXIST(args, "callbackId", out) + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); + CHECK_PRIVILEGE(kPrivilegeDataSharing); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeDataSharing, &out); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSArgumentChannel); + CHECK_EXIST(args, kJSCurrentListenerId); - auto stop = [this, args](const std::shared_ptr& result) { + auto stop = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("stop"); + TizenResult result = TizenSuccess(); + // Finding the service ConvergenceAppCommunicationService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 0, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service stop procedure + result = service->Stop(new ConvergenceChannel(ConvergenceUtils::GetArg(args, kJSArgumentChannel)), + static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - // Running the service stop procedure - service->Stop(new ConvergenceChannel(args.get(kJSArgumentChannel)), - static_cast(args.get(kJSCurrentListenerId).get())); - - picojson::object& object = result->get(); - object[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(object); - }; - - auto stop_result = - [this, args](const std::shared_ptr& result) { - ScopeLogger("stop_result"); - result->get()[kJSCallbackId] = args.get(kJSCallbackId); - Instance::PostMessage(this, result->serialize().c_str()); + this->Post(token, result); }; - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; + std::thread(stop, token).detach(); - TaskQueue::GetInstance().Queue( - stop, - stop_result, - data); - - ReportSuccess(out); + return TizenSuccess(); } -void ConvergenceInstance::AppCommunicationServiceSetListener( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationServiceSetListener(const picojson::object& args) { ScopeLogger(); - /*CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out) - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out) - CHECK_PRIVILEGE_ACCESS(kPrivilegeWifiDirect, &out)*/ + /*CHECK_PRIVILEGE(kPrivilegeInternet) + CHECK_PRIVILEGE(kPrivilegeBluetooth) + CHECK_PRIVILEGE(kPrivilegeWifiDirect)*/ - LoggerI("ARGS: %s", args.serialize().c_str()); + LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); // Finding the service ConvergenceAppCommunicationService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 0, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + LogAndReturnTizenError(common::NotFoundError("Can not find the service type = 1")); } // Running the service stop procedure - service->SetListener(static_cast(args.get(kJSCurrentListenerId).get())); + service->SetListener(static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); - ReportSuccess(out); + return common::TizenSuccess(); } -void ConvergenceInstance::AppCommunicationServiceUnsetListener( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationServiceUnsetListener(const picojson::object& args) { ScopeLogger(); - /*CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out) - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out) - CHECK_PRIVILEGE_ACCESS(kPrivilegeWifiDirect, &out)*/ + /*CHECK_PRIVILEGE(kPrivilegeInternet) + CHECK_PRIVILEGE(kPrivilegeBluetooth) + CHECK_PRIVILEGE(kPrivilegeWifiDirect)*/ // Finding the service ConvergenceAppCommunicationService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 0, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + LogAndReturnTizenError(common::NotFoundError("Can not find the service type = 1")); } // Running the service stop procedure service->RemoveListener(); - ReportSuccess(out); + return common::TizenSuccess(); } -void ConvergenceInstance::AppCommunicationServerServiceConstructLocal( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationServerServiceConstructLocal(const picojson::object& args) { ScopeLogger(); // Finding the service ConvergenceAppCommunicationClientService *service = static_cast( - ConvergenceManager::GetInstance(this).RegisterLocalService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).RegisterLocalService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 1, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + LogAndReturnTizenError(common::NotFoundError("Can not find the service type = 1")); } - ReportSuccess(out); + return common::TizenSuccess(); } -void ConvergenceInstance::AppCommunicationClientServiceConnect( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationClientServiceConnect(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); - CHECK_EXIST(args, "callbackId", out) + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); + CHECK_EXIST(args, kJSArgumentDeviceId); + CHECK_EXIST(args, kJSCurrentListenerId); - LoggerI("ARGS: %s", args.serialize().c_str()); + LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); - auto connect = - [this, args](const std::shared_ptr& result) { + auto connect = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("connect"); - // Finding the service + TizenResult result = TizenSuccess(); + ConvergenceAppCommunicationClientService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - LoggerE("Can not find the service type = 1, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - //ReportSuccess(object); // TODO ReportError - return; + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service connect procedure + result = service->Connect(static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - // Running the service connect procedure - service->Connect(static_cast(args.get(kJSCurrentListenerId).get())); - - picojson::object& object = result->get(); - object[kJSCallbackId] = args.get(kJSCallbackId); - ReportSuccess(object); - }; - - auto connect_result = - [this, args](const std::shared_ptr& result) { - ScopeLogger("connect_result"); - - result->get()[kJSCallbackId] = args.get(kJSCallbackId); - Instance::PostMessage(this, result->serialize().c_str()); + this->Post(token, result); }; - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; + std::thread(connect, token).detach(); - TaskQueue::GetInstance().Queue( - connect, - connect_result, - data); - ReportSuccess(out); + return TizenSuccess(); } -void ConvergenceInstance::AppCommunicationClientServiceDisconnect( - const picojson::value& args, picojson::object& out) { +common::TizenResult ConvergenceInstance::AppCommunicationClientServiceDisconnect(const picojson::object& args, + const common::AsyncToken& token) { ScopeLogger(); + CHECK_PRIVILEGE(kPrivilegeInternet); + CHECK_PRIVILEGE(kPrivilegeBluetooth); - CHECK_PRIVILEGE_ACCESS(kPrivilegeInternet, &out); - CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out); - - //LoggerI("ARGS: %s", args.serialize().c_str()); + //LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); - auto disconnect = - [this, args](const std::shared_ptr& result) { + auto disconnect = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("disconnect"); - // Finding the service + TizenResult result = TizenSuccess(); + ConvergenceAppCommunicationClientService *service = static_cast( - ConvergenceManager::GetInstance(this).GetService(args.get(kJSArgumentDeviceId).to_str().c_str(), + ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - //ReportSuccess(object); // TODO ReportError - LoggerE("Can not find the service type = 1, device_id = ", - args.get(kJSArgumentDeviceId).to_str().c_str()); - return; + result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + } else { + // Running the service disconnect procedure + result = service->Disconnect(); } - // Running the service disconnect procedure - service->Disconnect(); - - picojson::object& object = result->get(); - ReportSuccess(object); + this->Post(token, result); }; - auto data = - std::shared_ptr{new picojson::value{picojson::object()}}; + std::thread(disconnect, token).detach(); - TaskQueue::GetInstance().Async( - disconnect, - data); - ReportSuccess(out); + return TizenSuccess(); } diff --git a/src/convergence/convergence_instance.h b/src/convergence/convergence_instance.h index cd0ead66..5695157d 100644 --- a/src/convergence/convergence_instance.h +++ b/src/convergence/convergence_instance.h @@ -17,8 +17,10 @@ #ifndef CONVERGENCE_CONVERGENCE_INSTANCE_H_ #define CONVERGENCE_CONVERGENCE_INSTANCE_H_ -//#include "common/tizen_instance.h" +#include +#include "common/tizen_instance.h" #include "common/extension.h" +#include "common/tizen_result.h" namespace extension { namespace convergence { @@ -40,11 +42,7 @@ enum ConvergenceCallbacks { //kAppCommunicationClientServiceConnectCallback }; - -// TODO: inherit it by common::TizenInstance class -//class ConvergenceInstance : public common::TizenInstance { - -class ConvergenceInstance : public common::ParsedInstance { +class ConvergenceInstance : public common::TizenInstance { public: ConvergenceInstance(); virtual ~ConvergenceInstance(); @@ -53,32 +51,31 @@ class ConvergenceInstance : public common::ParsedInstance { int curListenerId, bool isSuccess, picojson::object& param); private: - // TODO: make all API functions return common::TizenResult - // Convergence Manager - void ConvergenceManagerStartDiscovery(const picojson::value& args, - picojson::object& out); - void ConvergenceManagerStopDiscovery(const picojson::value& args, - picojson::object& out); + common::TizenResult ConvergenceManagerStartDiscovery(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult ConvergenceManagerStopDiscovery(const picojson::object& args); // Remote App Control Service - void RemoteAppControlServiceConnect(const picojson::value& args, picojson::object& out); - void RemoteAppControlServiceDisconnect(const picojson::value& args, picojson::object& out); - void RemoteAppControlServiceLaunch(const picojson::value& args, picojson::object& out); + common::TizenResult RemoteAppControlServiceConnect(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult RemoteAppControlServiceDisconnect(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult RemoteAppControlServiceStart(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult RemoteAppControlServiceStop(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult RemoteAppControlServiceLaunch(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult RemoteAppControlServiceLaunchAppControl(const picojson::object& args, const common::AsyncToken& token); // App Communication Service - void AppCommunicationServiceStart(const picojson::value& args, picojson::object& out); - void AppCommunicationServiceStop(const picojson::value& args, picojson::object& out); - void AppCommunicationServiceSend(const picojson::value& args, picojson::object& out); - void AppCommunicationServiceSetListener(const picojson::value& args, picojson::object& out); - void AppCommunicationServiceUnsetListener(const picojson::value& args, picojson::object& out); + common::TizenResult AppCommunicationServiceStart(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult AppCommunicationServiceStop(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult AppCommunicationServiceSend(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult AppCommunicationServiceSetListener(const picojson::object& args); + common::TizenResult AppCommunicationServiceUnsetListener(const picojson::object& args); // App Communication Server Service - void AppCommunicationServerServiceConstructLocal(const picojson::value& args, picojson::object& out); + common::TizenResult AppCommunicationServerServiceConstructLocal(const picojson::object& args); // App Communication Client Service - void AppCommunicationClientServiceConnect(const picojson::value& args, picojson::object& out); - void AppCommunicationClientServiceDisconnect(const picojson::value& args, picojson::object& out); + common::TizenResult AppCommunicationClientServiceConnect(const picojson::object& args, const common::AsyncToken& token); + common::TizenResult AppCommunicationClientServiceDisconnect(const picojson::object& args, const common::AsyncToken& token); }; } // namespace convergence diff --git a/src/convergence/convergence_remote_app_control_service.cc b/src/convergence/convergence_remote_app_control_service.cc index 0b4c86ab..c957e63c 100644 --- a/src/convergence/convergence_remote_app_control_service.cc +++ b/src/convergence/convergence_remote_app_control_service.cc @@ -24,24 +24,30 @@ #include "convergence/convergence_payload.h" #include "convergence/convergence_utils.h" #include "common/logger.h" +#include "common/scope_exit.h" namespace extension { namespace convergence { +namespace { +static const char* kAppControl = "app_control"; +static const char* kReply = "reply"; +} // namespace + using common::TizenResult; using common::TizenSuccess; ConvergenceRemoteAppControlService::ConvergenceRemoteAppControlService() : ConvergenceService() - , started_(false) - , connect_callback_param_(nullptr) { + , connect_callback_param_(nullptr) + , started_(false) { ScopeLogger(); } ConvergenceRemoteAppControlService::ConvergenceRemoteAppControlService(conv_device_h device, ConvergenceInstance *convergence_plugin) : ConvergenceService(device, CONV_SERVICE_REMOTE_APP_CONTROL, convergence_plugin) - , started_(false) - , connect_callback_param_(nullptr) { + , connect_callback_param_(nullptr) + , started_(false) { ScopeLogger(); } @@ -87,7 +93,7 @@ void ConvergenceRemoteAppControlService::ServiceConnectedCb(conv_service_h servi } } -common::TizenResult ConvergenceRemoteAppControlService::Connect(const int cur_listener_id) { +TizenResult ConvergenceRemoteAppControlService::Connect(const int cur_listener_id) { ScopeLogger(); conv_service_h service = FindServiceHandle(); @@ -112,7 +118,7 @@ common::TizenResult ConvergenceRemoteAppControlService::Connect(const int cur_li return TizenSuccess(); } -common::TizenResult ConvergenceRemoteAppControlService::Disconnect() { +TizenResult ConvergenceRemoteAppControlService::Disconnect() { ScopeLogger(); conv_service_h service = FindServiceHandle(); @@ -134,6 +140,60 @@ common::TizenResult ConvergenceRemoteAppControlService::Disconnect() { return TizenSuccess(); } +TizenResult ConvergenceRemoteAppControlService::Start(const bool reply, const int cur_listener_id) { + ScopeLogger(); + + if (started_) { + return LogAndCreateTizenError(InvalidStateError, "RemoteAppControlService already started"); + } + + conv_service_h service = FindServiceHandle(); + if (!service) { + return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); + } + + if (reply) { + UpdateListener(cur_listener_id); + } + + const int error = conv_service_start(service, nullptr, nullptr); + if (CONV_ERROR_NONE != error) { + return LogAndCreateTizenError(AbortError, "conv_service_start error"); + } else { + LoggerI("RemoteAppControlService started"); + started_ = true; + } + + return TizenSuccess(); +} + +TizenResult ConvergenceRemoteAppControlService::Stop(const bool reply, const int cur_listener_id) { + ScopeLogger(); + + if (!started_) { + return LogAndCreateTizenError(InvalidStateError, "RemoteAppControlService is not started yet"); + } + + conv_service_h service = FindServiceHandle(); + if (!service) { + return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); + } + + if (reply) { + UpdateListener(cur_listener_id); + } + + const int error = conv_service_stop(service, nullptr, nullptr); + if (CONV_ERROR_NONE != error) { + return LogAndCreateTizenError(AbortError, "conv_service_stop error"); + } else { + LoggerI("RemoteAppControlService stopped"); + started_ = false; + } + + return TizenSuccess(); +} + void ConvergenceRemoteAppControlService::ServiceListenerCb(conv_service_h service_handle, conv_channel_h channel_handle, conv_error_e error, conv_payload_h result, void* user_data) { @@ -194,108 +254,250 @@ void ConvergenceRemoteAppControlService::UpdateListener(const int cur_listener_i } } -void ConvergenceRemoteAppControlService::EnsureStarted() { +TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool reply, const int cur_listener_id) { ScopeLogger(); - if (started_) - return; + + if (!started_) { + return LogAndCreateTizenError(InvalidStateError, "RemoteAppControlService not started"); + } + + conv_payload_h payload = nullptr; + app_control_h app_control = nullptr; + + SCOPE_EXIT { + if (payload) { + conv_payload_destroy(payload); + } + if (app_control) { + app_control_destroy(app_control); + } + }; conv_service_h service_handle = FindServiceHandle(); if (!service_handle) { - LoggerE("AAAAAA!!! Service not found"); - return; // TODO handle error + return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); } - const int error = conv_service_start(service_handle, nullptr, nullptr); - if (CONV_ERROR_NONE != error) { - // TODO: Handle error - trace_conv_error(error, __LINE__, "conv_service_publish START"); - } else { - LoggerI("APP CONTROL SERVICE IS STARTED"); - started_ = true; + int ret = conv_payload_create(&payload); + if (CONV_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to create payload handle"); } -} -common::TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool reply, const int cur_listener_id) { - ScopeLogger(); + ret = app_control_create(&app_control); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to create app control handle"); + } - conv_service_h service_handle = FindServiceHandle(); - if (!service_handle) { - LoggerE("AAAAAA!!! Service not found"); - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + ret = app_control_set_app_id(app_control, appId); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app ID in app control"); + } + + ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_MAIN); + if (CONV_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set operation in app control"); + } + + ret = conv_payload_set_app_control(payload, kAppControl, app_control); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app control in payload"); } - // Create app control payload with passed appId - conv_payload_h payload = CreateAppIdPayload(appId, reply); - if (!payload) { - return LogAndCreateTizenError(AbortError, - "Failed to get payload handle"); + if (reply) { + ret = conv_payload_set_string(payload, kReply, "1"); + if (CONV_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set string in payload"); + } } // Update listener: assign it if it is not yet assigned - if (reply) + if (reply) { UpdateListener(cur_listener_id); - - // Ensure the service was started - EnsureStarted(); + } // Sending app control on the remote device - const int error = conv_service_publish(service_handle, nullptr, payload); - if (CONV_ERROR_NONE != error) { - // TODO: Handle error - trace_conv_error(error, __LINE__, "conv_service_publish LAUNCH"); + ret = conv_service_publish(service_handle, nullptr, payload); + if (CONV_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to launch appControl"); } else { - LoggerI("---- SEEMS APP CONTROL WAS LAUNCHED ----"); + LoggerD("appControl launched"); } - conv_payload_destroy(payload); return TizenSuccess(); } -conv_payload_h ConvergenceRemoteAppControlService::CreateAppIdPayload(const char *appId, bool reply) const { +TizenResult ConvergenceRemoteAppControlService::LaunchAppControl(const picojson::object& jsonAppControl, + const char *appId, + bool reply, + const int cur_listener_id) { ScopeLogger(); - conv_payload_h payload = nullptr; - int error = conv_payload_create(&payload); - if (CONV_ERROR_NONE != error) { - LoggerE("ERROR! Failed to create payload handle: [%d]", error); - return nullptr; + if (!started_) { + return LogAndCreateTizenError(InvalidStateError, "RemoteAppControlService not started"); } + conv_payload_h payload = nullptr; app_control_h app_control = nullptr; - error = app_control_create(&app_control); - if (APP_CONTROL_ERROR_NONE != error) { - LoggerE("ERROR! Failed to create app control handle: [%d]", error); - return nullptr; + + SCOPE_EXIT { + if (payload) { + conv_payload_destroy(payload); + } + if (app_control) { + app_control_destroy(app_control); + } + }; + + // Get service_handle + conv_service_h service_handle = FindServiceHandle(); + if (!service_handle) { + return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); } - error = app_control_set_app_id(app_control, appId); - if (APP_CONTROL_ERROR_NONE != error) { - LoggerE("ERROR! Failed to set app ID in app control: [%d]", error); - return nullptr; + // Create payload + int ret = conv_payload_create(&payload); + if (CONV_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to create payload handle"); } - error = app_control_set_operation(app_control, APP_CONTROL_OPERATION_MAIN); - if (CONV_ERROR_NONE != error) { - LoggerE("ERROR! Failed to set operation in app control: [%d]", error); - return nullptr; + // Create app control + ret = app_control_create(&app_control); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to create app control handle"); + } + + // Set app id + if (appId && strlen(appId)) { + ret = app_control_set_app_id(app_control, appId); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app ID in app control"); + } + } + + // Set app control + const auto it_operation = jsonAppControl.find("operation"); + const auto it_uri = jsonAppControl.find("uri"); + const auto it_mime = jsonAppControl.find("mime"); + const auto it_category = jsonAppControl.find("category"); + const auto it_data = jsonAppControl.find("data"); + const auto it_app_control_end = jsonAppControl.end(); + + if (it_operation == it_app_control_end || + it_uri == it_app_control_end || + it_mime == it_app_control_end || + it_category == it_app_control_end || + it_data == it_app_control_end || + !it_operation->second.is() || + !it_data->second.is()) { + return LogAndCreateTizenError(InvalidValuesError, "Invalid parameter was passed."); + } + + // operation + ret = app_control_set_operation(app_control, it_operation->second.get().c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app control operation"); } - error = conv_payload_set_app_control(payload, "app_control", app_control); - if (APP_CONTROL_ERROR_NONE != error) { - LoggerE("ERROR! Failed to set app control in payload: [%d]", error); - return nullptr; + // uri + if (it_uri->second.is()) { + ret = app_control_set_uri(app_control, it_uri->second.get().c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app control uri"); + } + } + + // mime + if (it_mime->second.is()) { + ret = app_control_set_mime(app_control, it_mime->second.get().c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app control mime"); + } + } + + // category + if (it_category->second.is()) { + ret = app_control_set_category(app_control, it_category->second.get().c_str()); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app control category"); + } + } + + // ApplicationControlData + const picojson::array& data = it_data->second.get(); + + for (auto iter = data.begin(); iter != data.end(); ++iter) { + if (iter->is()) { + TizenResult result = ApplicationControlDataToServiceExtraData(iter->get(), app_control); + if (!result) { + return result; + } + } + } + + ret = conv_payload_set_app_control(payload, kAppControl, app_control); + if (APP_CONTROL_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set app control in payload"); } if (reply) { - error = conv_payload_set_string(payload, "reply", "1"); - if (CONV_ERROR_NONE != error) { - LoggerE("ERROR! Failed to set string in payload: [%d]", error); - return nullptr; + ret = conv_payload_set_string(payload, kReply, "1"); + if (CONV_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to set string in payload"); } } - return payload; + // Update listener: assign it if it is not yet assigned + if (reply) { + UpdateListener(cur_listener_id); + } + + // Sending app control on the remote device + ret = conv_service_publish(service_handle, nullptr, payload); + if (CONV_ERROR_NONE != ret) { + return LogAndCreateTizenError(AbortError, "Failed to launch appControl"); + } else { + LoggerD("appControl launched"); + } + + return TizenSuccess(); +} + +TizenResult ConvergenceRemoteAppControlService::ApplicationControlDataToServiceExtraData( + const picojson::object& app_control_data, + app_control_h app_control) { + ScopeLogger(); + + const auto it_key = app_control_data.find("key"); + const auto it_value = app_control_data.find("value"); + const auto it_app_control_data_end = app_control_data.end(); + + if (it_key == it_app_control_data_end || + it_value == it_app_control_data_end || + !it_key->second.is() || + !it_value->second.is()) { + return LogAndCreateTizenError(InvalidValuesError, "Invalid parameter was passed."); + } + + const std::string& key = it_key->second.get(); + const picojson::array& value = it_value->second.get(); + + const size_t size = value.size(); + const char** arr = new const char*[size]; + size_t i = 0; + + for (auto iter = value.begin(); iter != value.end(); ++iter, ++i) { + arr[i] = iter->to_str().c_str(); + } + + if (1 == size) { + app_control_add_extra_data(app_control, key.c_str(), arr[0]); + } else { + app_control_add_extra_data_array(app_control, key.c_str(), arr, size); + } + + delete[] arr; + + return TizenSuccess(); } } // namespace convergence diff --git a/src/convergence/convergence_remote_app_control_service.h b/src/convergence/convergence_remote_app_control_service.h index b82092ba..a43294f4 100644 --- a/src/convergence/convergence_remote_app_control_service.h +++ b/src/convergence/convergence_remote_app_control_service.h @@ -43,11 +43,18 @@ class ConvergenceRemoteAppControlService : public ConvergenceService { public: common::TizenResult Connect(const int cur_listener_id); common::TizenResult Disconnect(); + common::TizenResult Start(const bool reply, const int cur_listener_id); + common::TizenResult Stop(const bool reply, const int cur_listener_id); common::TizenResult Launch(const char *appId, bool reply, const int cur_listener_id); + common::TizenResult LaunchAppControl(const picojson::object& jsonAppControl, + const char *appId, + bool reply, + const int cur_listener_id); private: - conv_payload_h CreateAppIdPayload(const char *appId, bool reply) const; + common::TizenResult ApplicationControlDataToServiceExtraData( + const picojson::object& app_control_data, + app_control_h app_control); void UpdateListener(const int cur_listener_id); - void EnsureStarted(); static void ServiceConnectedCb(conv_service_h service_handle, conv_error_e error, conv_payload_h result, void* user_data); static void ServiceListenerCb(conv_service_h service_handle, diff --git a/src/convergence/convergence_utils.cc b/src/convergence/convergence_utils.cc index 86e81c04..525b4284 100644 --- a/src/convergence/convergence_utils.cc +++ b/src/convergence/convergence_utils.cc @@ -21,14 +21,12 @@ #include #include "convergence/convergence_instance.h" +#include "convergence/convergence_utils.h" #include "common/logger.h" namespace extension { namespace convergence { - - - void trace_conv_error(const int error, int line_number, const char *extra_text) { std::string error_text; switch (error) { @@ -65,7 +63,16 @@ void trace_conv_error(const int error, int line_number, const char *extra_text) } } +const picojson::value& ConvergenceUtils::GetArg(const picojson::object& args, const std::string& name) { + static const picojson::value kNull; + auto it = args.find(name); + if (args.end() == it) { + return kNull; + } else { + return it->second; + } +} } // namespace convergence } // namespace extension diff --git a/src/convergence/convergence_utils.h b/src/convergence/convergence_utils.h index e1292160..a7aa2806 100644 --- a/src/convergence/convergence_utils.h +++ b/src/convergence/convergence_utils.h @@ -28,6 +28,11 @@ namespace extension { namespace convergence { +#define CHECK_EXIST(args, name) \ + if (args.end() == args.find(name)) { \ + return common::TypeMismatchError(std::string(name) + " is required argument"); \ + } + class ConvergenceInstance; namespace { @@ -65,6 +70,11 @@ struct CallbackParam { void trace_conv_error(const int error, int line_number, const char *extra_text); +class ConvergenceUtils { + public: + static const picojson::value& GetArg(const picojson::object& args, const std::string& name); +}; + } // namespace convergence } // namespace extension -- 2.34.1