[Convergence] - Functions return TizenResult and launchAppControl, start and stop... 98/97198/9
authorAndrzej Popowski <a.popowski@samsung.com>
Fri, 11 Nov 2016 06:44:55 +0000 (15:44 +0900)
committerAndrzej Popowski <a.popowski@samsung.com>
Fri, 18 Nov 2016 04:20:47 +0000 (13:20 +0900)
Change-Id: Ief1d4df70193ea98f342dce566d5af52d2834979
Signed-off-by: Andrzej Popowski <a.popowski@samsung.com>
src/convergence/convergence_api.js
src/convergence/convergence_instance.cc
src/convergence/convergence_instance.h
src/convergence/convergence_remote_app_control_service.cc
src/convergence/convergence_remote_app_control_service.h
src/convergence/convergence_utils.cc
src/convergence/convergence_utils.h

index dd7be5c03e9720692c7e853ecab21d6ed63d8797..7cad85002f28dc849af2bd09ca4f62d336182024 100644 (file)
@@ -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);
 };
index 06e80953871bec51721f60602f2d9182334ca554..51316fcffad2b1355b25ecedf8e43dfefbabd1ee 100644 (file)
 
 #include <functional>
 #include <string>
+#include <thread>
 
 #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<picojson::value>& result) {
+  auto start_discovery = [this, args](const common::AsyncToken& token) -> void {
     ScopeLogger("start_discovery");
 
     // Start the discovery procedure
-    ConvergenceManager::GetInstance(this).StartDiscovery(
-      static_cast<long>(args.get(kJSArgumentTimeout).get<double>()));
-
-    picojson::object& object = result->get<picojson::object>();
-    object[kJSCallbackId] = args.get(kJSCallbackId);
-    ReportSuccess(object);
+    TizenResult result = ConvergenceManager::GetInstance(this).StartDiscovery(
+                                static_cast<long>(ConvergenceUtils::GetArg(args, kJSArgumentTimeout).get<double>()));
+    this->Post(token, result);
   };
 
-  auto start_discovery_result =
-    [this, args](const std::shared_ptr<picojson::value>& result) {
-    ScopeLogger("start_discovery_result");
-    result->get<picojson::object>()[kJSCallbackId] = args.get(kJSCallbackId);
-    Instance::PostMessage(this, result->serialize().c_str());
-  };
-
-  auto data =
-    std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
+  std::thread(start_discovery, token).detach();
 
-  TaskQueue::GetInstance().Queue<picojson::value>(
-    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<picojson::value>& result) {
+  auto connect = [this, args](const common::AsyncToken& token) -> void {
     ScopeLogger("connect");
 
+    TizenResult result = TizenSuccess();
+
     // Finding the service
     ConvergenceRemoteAppControlService *service =
       static_cast<ConvergenceRemoteAppControlService *>(
-        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<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
     }
 
-    // Running the service connect procedure
-    service->Connect(static_cast<int>(args.get(kJSCurrentListenerId).get<double>()));
-
-    picojson::object& object = result->get<picojson::object>();
-    object[kJSCallbackId] = args.get(kJSCallbackId);
-    ReportSuccess(object);
+    this->Post(token, result);
   };
 
-  auto connect_result =
-    [this, args](const std::shared_ptr<picojson::value>& result) {
-    ScopeLogger("connect_result");
+  std::thread(connect, token).detach();
 
-    result->get<picojson::object>()[kJSCallbackId] = args.get(kJSCallbackId);
-    Instance::PostMessage(this, result->serialize().c_str());
-  };
+  return TizenSuccess();
+}
 
-  auto data =
-    std::shared_ptr<picojson::value>{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<picojson::value>(
-    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<ConvergenceRemoteAppControlService *>(
+        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<picojson::value>& result) {
-    ScopeLogger("disconnect");
+  auto start = [this, args](const common::AsyncToken& token) -> void {
+    ScopeLogger("start");
+
+    TizenResult result = TizenSuccess();
 
     // Finding the service
     ConvergenceRemoteAppControlService *service =
       static_cast<ConvergenceRemoteAppControlService *>(
-        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<bool>(ConvergenceUtils::GetArg(args, kJSArgumentReply).get<bool>()),
+                              static_cast<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
     }
 
-    // Running the service disconnect procedure
-    service->Disconnect();
-
-    picojson::object& object = result->get<picojson::object>();
-    ReportSuccess(object);
+    this->Post(token, result);
   };
 
-  auto data =
-    std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
-
-  TaskQueue::GetInstance().Async<picojson::value>(
-      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<picojson::value>& 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<ConvergenceRemoteAppControlService *>(
-        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<bool>(ConvergenceUtils::GetArg(args, kJSArgumentReply).get<bool>()),
+                             static_cast<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
     }
 
-    // Running the service app control procedure
-    service->Launch(
-      args.get(kJSArgumentAppId).to_str().c_str(),
-      static_cast<bool>(args.get(kJSArgumentReply).get<bool>()),
-      static_cast<int>(args.get(kJSCurrentListenerId).get<double>()));
-
-    picojson::object& object = result->get<picojson::object>();
-    object[kJSCallbackId] = args.get(kJSCallbackId);
-    ReportSuccess(object);
+    this->Post(token, result);
   };
 
-  auto launch_result =
-    [this, args](const std::shared_ptr<picojson::value>& result) {
-    ScopeLogger("send_result");
-    result->get<picojson::object>()[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<ConvergenceRemoteAppControlService *>(
+        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<bool>(ConvergenceUtils::GetArg(args, kJSArgumentReply).get<bool>()),
+                  static_cast<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
+    }
+
+    this->Post(token, result);
   };
 
-  auto data =
-    std::shared_ptr<picojson::value>{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<picojson::value>(
-    launch,
-    launch_result,
-    data);
+    TizenResult result = TizenSuccess();
 
-  ReportSuccess(out);
+    // Finding the service
+    ConvergenceRemoteAppControlService *service =
+      static_cast<ConvergenceRemoteAppControlService *>(
+        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<picojson::object>(),
+                                         ConvergenceUtils::GetArg(args, kJSArgumentAppId).to_str().c_str(),
+                                         ConvergenceUtils::GetArg(args, kJSArgumentReply).get<bool>(),
+                                         static_cast<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
+    }
+
+    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<picojson::value>& result) {
+  auto start = [this, args](const common::AsyncToken& token) -> void {
     ScopeLogger("start");
 
+    TizenResult result = TizenSuccess();
+
     // Finding the service
     ConvergenceAppCommunicationService *service =
       static_cast<ConvergenceAppCommunicationService *>(
-        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<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
     }
 
-    // Running the service start procedure
-    service->Start(new ConvergenceChannel(args.get(kJSArgumentChannel)),
-      static_cast<int>(args.get(kJSCurrentListenerId).get<double>()));
-
-    picojson::object& object = result->get<picojson::object>();
-    object[kJSCallbackId] = args.get(kJSCallbackId);
-    ReportSuccess(object);
+    this->Post(token, result);
   };
 
-  auto start_result =
-    [this, args](const std::shared_ptr<picojson::value>& result) {
-    ScopeLogger("start_result");
-    result->get<picojson::object>()[kJSCallbackId] = args.get(kJSCallbackId);
-    Instance::PostMessage(this, result->serialize().c_str());
-  };
-
-  auto data = std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
+  std::thread(start, token).detach();
 
-  TaskQueue::GetInstance().Queue<picojson::value>(
-    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<picojson::value>& result) {
+  auto send = [this, args](const common::AsyncToken& token) -> void {
     ScopeLogger("send");
 
+    TizenResult result = TizenSuccess();
+
     // Finding the service
     ConvergenceAppCommunicationService *service =
       static_cast<ConvergenceAppCommunicationService *>(
-        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<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
 
-    // Running the service send procedure
-    service->Send(new ConvergenceChannel(args.get(kJSArgumentChannel)),
-      new ConvergencePayloadArray(args.get(kJSArgumentPayload)),
-      static_cast<int>(args.get(kJSCurrentListenerId).get<double>()));
-
-    picojson::object& object = result->get<picojson::object>();
-    object[kJSCallbackId] = args.get(kJSCallbackId);
-    ReportSuccess(object);
-  };
+    }
 
-  auto send_result =
-    [this, args](const std::shared_ptr<picojson::value>& result) {
-    ScopeLogger("send_result");
-    result->get<picojson::object>()[kJSCallbackId] = args.get(kJSCallbackId);
-    Instance::PostMessage(this, result->serialize().c_str());
+    this->Post(token, result);
   };
 
-  auto data =
-    std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
-
-  TaskQueue::GetInstance().Queue<picojson::value>(
-    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<picojson::value>& result) {
+  auto stop = [this, args](const common::AsyncToken& token) -> void {
     ScopeLogger("stop");
 
+    TizenResult result = TizenSuccess();
+
     // Finding the service
     ConvergenceAppCommunicationService *service =
       static_cast<ConvergenceAppCommunicationService *>(
-        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<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
     }
 
-    // Running the service stop procedure
-    service->Stop(new ConvergenceChannel(args.get(kJSArgumentChannel)),
-      static_cast<int>(args.get(kJSCurrentListenerId).get<double>()));
-
-    picojson::object& object = result->get<picojson::object>();
-    object[kJSCallbackId] = args.get(kJSCallbackId);
-    ReportSuccess(object);
-  };
-
-  auto stop_result =
-    [this, args](const std::shared_ptr<picojson::value>& result) {
-    ScopeLogger("stop_result");
-    result->get<picojson::object>()[kJSCallbackId] = args.get(kJSCallbackId);
-    Instance::PostMessage(this, result->serialize().c_str());
+    this->Post(token, result);
   };
 
-  auto data =
-    std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
+  std::thread(stop, token).detach();
 
-  TaskQueue::GetInstance().Queue<picojson::value>(
-    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<ConvergenceAppCommunicationService *>(
-      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<int>(args.get(kJSCurrentListenerId).get<double>()));
+  service->SetListener(static_cast<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
 
-  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<ConvergenceAppCommunicationService *>(
-      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<ConvergenceAppCommunicationClientService *>(
-      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<picojson::value>& result) {
+  auto connect = [this, args](const common::AsyncToken& token) -> void {
     ScopeLogger("connect");
 
-    // Finding the service
+    TizenResult result = TizenSuccess();
+
     ConvergenceAppCommunicationClientService *service =
       static_cast<ConvergenceAppCommunicationClientService *>(
-        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<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>()));
     }
 
-    // Running the service connect procedure
-    service->Connect(static_cast<int>(args.get(kJSCurrentListenerId).get<double>()));
-
-    picojson::object& object = result->get<picojson::object>();
-    object[kJSCallbackId] = args.get(kJSCallbackId);
-    ReportSuccess(object);
-  };
-
-  auto connect_result =
-    [this, args](const std::shared_ptr<picojson::value>& result) {
-    ScopeLogger("connect_result");
-
-    result->get<picojson::object>()[kJSCallbackId] = args.get(kJSCallbackId);
-    Instance::PostMessage(this, result->serialize().c_str());
+    this->Post(token, result);
   };
 
-  auto data =
-    std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
+  std::thread(connect, token).detach();
 
-  TaskQueue::GetInstance().Queue<picojson::value>(
-    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<picojson::value>& result) {
+  auto disconnect = [this, args](const common::AsyncToken& token) -> void {
     ScopeLogger("disconnect");
 
-    // Finding the service
+    TizenResult result = TizenSuccess();
+
     ConvergenceAppCommunicationClientService *service =
       static_cast<ConvergenceAppCommunicationClientService *>(
-        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<picojson::object>();
-    ReportSuccess(object);
+    this->Post(token, result);
   };
 
-  auto data =
-    std::shared_ptr<picojson::value>{new picojson::value{picojson::object()}};
+  std::thread(disconnect, token).detach();
 
-  TaskQueue::GetInstance().Async<picojson::value>(
-      disconnect,
-      data);
-  ReportSuccess(out);
+  return TizenSuccess();
 }
 
 
index cd0ead66393a183685a6fe69e56fbfe26aaef173..5695157dec95d3ee69d83f4e8ddbb63ba9ba22d1 100644 (file)
 #ifndef CONVERGENCE_CONVERGENCE_INSTANCE_H_
 #define CONVERGENCE_CONVERGENCE_INSTANCE_H_
 
-//#include "common/tizen_instance.h"
+#include <d2d_conv_manager.h>
+#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
index 0b4c86abfc36a141200a26d801299b0355e85468..c957e63c5273b68673b638c2d07814d162ba44f9 100644 (file)
 #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<std::string>() ||
+      !it_data->second.is<picojson::array>()) {
+    return LogAndCreateTizenError(InvalidValuesError, "Invalid parameter was passed.");
+  }
+
+  // operation
+  ret = app_control_set_operation(app_control, it_operation->second.get<std::string>().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<std::string>()) {
+    ret = app_control_set_uri(app_control, it_uri->second.get<std::string>().c_str());
+    if (APP_CONTROL_ERROR_NONE != ret) {
+      return LogAndCreateTizenError(AbortError, "Failed to set app control uri");
+    }
+  }
+
+  // mime
+  if (it_mime->second.is<std::string>()) {
+    ret = app_control_set_mime(app_control, it_mime->second.get<std::string>().c_str());
+    if (APP_CONTROL_ERROR_NONE != ret) {
+      return LogAndCreateTizenError(AbortError, "Failed to set app control mime");
+    }
+  }
+
+  // category
+  if (it_category->second.is<std::string>()) {
+    ret = app_control_set_category(app_control, it_category->second.get<std::string>().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<picojson::array>();
+
+  for (auto iter = data.begin(); iter != data.end(); ++iter) {
+    if (iter->is<picojson::object>()) {
+      TizenResult result = ApplicationControlDataToServiceExtraData(iter->get<picojson::object>(), 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<std::string>() ||
+      !it_value->second.is<picojson::array>()) {
+    return LogAndCreateTizenError(InvalidValuesError, "Invalid parameter was passed.");
+  }
+
+  const std::string& key = it_key->second.get<std::string>();
+  const picojson::array& value = it_value->second.get<picojson::array>();
+
+  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
index b82092ba69111ac01fabec5643f3e8e27941a5ab..a43294f4f1d970ca17f85afaf0038fe840245ab6 100644 (file)
@@ -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,
index 86e81c04bfaeecd643214db17d56c6a11109562d..525b4284e4b206c0401dc411a0e4cc69bd016592 100644 (file)
 #include <d2d_conv_internal.h>
 
 #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
index e12921603a24ca192b009afb304da9616526de3e..a7aa2806cb9c6428f0b86d02eeafc333204c6c2d 100644 (file)
 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