From ee81f451bb9a92c0bdab5f784cb6e4219b5c70bb Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Fri, 25 Nov 2016 15:50:30 +0900 Subject: [PATCH 01/16] [Convergence] Fix for ConvergenceChannel. [Feature] Create channel only in start() method. Other methods related to Channel cause errors in case channel is not present in channels vector. [Verification] Code compiles. Change-Id: Ibfaf6cde17f323fffcefc5b67b7e96a28498617c Signed-off-by: Tomasz Marciniak --- src/convergence/convergence_api.js | 19 ------- .../convergence_app_communication_service.cc | 34 +++++------- .../convergence_app_communication_service.h | 8 +-- src/convergence/convergence_instance.cc | 62 ++++++++++++++++------ src/convergence/convergence_service.cc | 31 ++++++++++- src/convergence/convergence_service.h | 3 ++ 6 files changed, 96 insertions(+), 61 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index 7221f36..a61c8c3 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -620,11 +620,6 @@ function AppCommunicationService() { value: null, writable: true, enumerable: false - }, - _isStarted : { - value: false, - writable: true, - enumerable: false } }); @@ -669,7 +664,6 @@ native_.addListener('APP_COMMUNICATION_SERVICE_LISTENER', function(result) { native_.callIfPossible(s._connectCallback, s); break; case 'onStart': - s._isStarted = true; native_.callIfPossible(s._startCallback, new ChannelInfo(result.channel.uri, result.channel.id), null); break; @@ -678,7 +672,6 @@ native_.addListener('APP_COMMUNICATION_SERVICE_LISTENER', function(result) { new ChannelInfo(result.channel.uri, result.channel.id), null); break; case 'onStop': - s._isStarted = false; native_.callIfPossible(s._stopCallback, new ChannelInfo(result.channel.uri, result.channel.id), null); break; @@ -747,10 +740,6 @@ AppCommunicationService.prototype.start = function(channel, successCallback, err } ]); - if (this._isStarted) { - throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Service already started.'); - } - var lid = this._serviceId; this._startCallback = successCallback; convergenceServices[lid] = this; @@ -795,10 +784,6 @@ AppCommunicationService.prototype.stop = function(channel, successCallback, erro } ]); - if (!this._isStarted) { - throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Service is not started.'); - } - var lid = -1; if (successCallback) { lid = this._serviceId; @@ -852,10 +837,6 @@ AppCommunicationService.prototype.send = function(channel, payload, successCallb } ]); - if (!this._isStarted) { - throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Service is not started.'); - } - var lid = this._serviceId; this._sendCallback = successCallback; convergenceServices[lid] = this; diff --git a/src/convergence/convergence_app_communication_service.cc b/src/convergence/convergence_app_communication_service.cc index 8a80eb7..41b8fca 100644 --- a/src/convergence/convergence_app_communication_service.cc +++ b/src/convergence/convergence_app_communication_service.cc @@ -85,7 +85,7 @@ common::TizenResult ConvergenceAppCommunicationService::Start( } common::TizenResult ConvergenceAppCommunicationService::Stop( - ConvergenceChannel& channel, + ConvergenceChannel* channel, const int cur_listener_id) { ScopeLogger(); @@ -96,28 +96,18 @@ common::TizenResult ConvergenceAppCommunicationService::Stop( UpdateListener(cur_listener_id); - const int error = conv_service_stop(service_handle, channel.GetHandle(), nullptr); + const int error = conv_service_stop(service_handle, channel->GetHandle(), nullptr); if (CONV_ERROR_NONE != error) { - return LogAndCreateTizenError(AbortError, "Failed to stop service"); + return LogAndCreateTizenError(AbortError, "Failed to stop service channel"); } - std::string removed_uri = channel.GetUri(); - std::string removed_id = channel.GetId(); - - for (auto it = opened_channels.begin(); it != opened_channels.end(); ++it){ - if((*it)->GetUri() == removed_uri && (*it)->GetId() == removed_id) { - LoggerD("Removing channel uri: [%s] id: [%s]", removed_uri.c_str(), removed_id.c_str()); - delete *it; - (*it) = nullptr; - opened_channels.erase(it); - break; - } - } + delete channel; + channel = nullptr; return TizenSuccess(); } -common::TizenResult ConvergenceAppCommunicationService::GetClientList(ConvergenceChannel& channel, +common::TizenResult ConvergenceAppCommunicationService::GetClientList(ConvergenceChannel* channel, const int cur_listener_id) { ScopeLogger(); @@ -129,16 +119,16 @@ common::TizenResult ConvergenceAppCommunicationService::GetClientList(Convergenc UpdateListener(cur_listener_id); - const int ret = conv_service_read(service_handle, channel.GetHandle(), nullptr); + const int ret = conv_service_read(service_handle, channel->GetHandle(), nullptr); if (CONV_ERROR_NONE != ret) { - return LogAndCreateTizenError(AbortError, "conv_service_stop error"); + return LogAndCreateTizenError(AbortError, "conv_service_read error"); } return TizenSuccess(); } common::TizenResult ConvergenceAppCommunicationService::Send( - ConvergenceChannel& channel, + ConvergenceChannel* channel, ConvergencePayloadArray& payload, const int cur_listener_id) { ScopeLogger(); @@ -150,7 +140,7 @@ common::TizenResult ConvergenceAppCommunicationService::Send( UpdateListener(cur_listener_id); - const int error = conv_service_publish(service_handle, channel.GetHandle(), payload.GetHandle()); + const int error = conv_service_publish(service_handle, channel->GetHandle(), payload.GetHandle()); if (CONV_ERROR_NONE != error) { return LogAndCreateTizenError(AbortError, "Failed to publish message"); } else { @@ -386,7 +376,7 @@ common::TizenResult ConvergenceAppCommunicationServerService::Start( } common::TizenResult ConvergenceAppCommunicationServerService::Stop( - ConvergenceChannel& channel, + ConvergenceChannel* channel, const int cur_listener_id) { ScopeLogger(); @@ -397,7 +387,7 @@ common::TizenResult ConvergenceAppCommunicationServerService::Stop( picojson::object param; param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusOk); - param[kChannel] = ConvergenceChannel::ToJson(channel.GetHandle()); + param[kChannel] = ConvergenceChannel::ToJson(channel->GetHandle()); param[kServiceResultType] = picojson::value(kServiceResultTypeOnStop); common::TizenResult result = ConvergenceAppCommunicationService::Stop(channel, cur_listener_id); diff --git a/src/convergence/convergence_app_communication_service.h b/src/convergence/convergence_app_communication_service.h index ed759d3..3821886 100644 --- a/src/convergence/convergence_app_communication_service.h +++ b/src/convergence/convergence_app_communication_service.h @@ -45,11 +45,11 @@ class ConvergenceAppCommunicationService : public ConvergenceService { public: virtual common::TizenResult Start(ConvergenceChannel* channel, const int cur_listener_id); - virtual common::TizenResult Stop(ConvergenceChannel& channel, + virtual common::TizenResult Stop(ConvergenceChannel* channel, const int cur_listener_id); - virtual common::TizenResult GetClientList(ConvergenceChannel& channel, + virtual common::TizenResult GetClientList(ConvergenceChannel* channel, const int cur_listener_id); - virtual common::TizenResult Send(ConvergenceChannel& channel, + virtual common::TizenResult Send(ConvergenceChannel* channel, ConvergencePayloadArray& payload, const int cur_listener_id); common::TizenResult SetListener(const int cur_listener_id); @@ -77,7 +77,7 @@ class ConvergenceAppCommunicationServerService : public ConvergenceAppCommunicat public: virtual common::TizenResult Start(ConvergenceChannel* channel, const int cur_listener_id); - virtual common::TizenResult Stop(ConvergenceChannel& channel, + virtual common::TizenResult Stop(ConvergenceChannel* channel, const int cur_listener_id); }; diff --git a/src/convergence/convergence_instance.cc b/src/convergence/convergence_instance.cc index 91f6c4d..c905ee4 100644 --- a/src/convergence/convergence_instance.cc +++ b/src/convergence/convergence_instance.cc @@ -430,11 +430,17 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceStart(const pico result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); } else { // Running the service start procedure - ConvergenceChannel* channel = new ConvergenceChannel - (ConvergenceUtils::GetArg(args, kJSArgumentChannel)); // memory would be managed in Start method - const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); + auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); + std::vector::iterator channel_it = service->GetChannel(channel_arg); - result = service->Start(channel, id); + if (service->IsChannelStarted(channel_it)) { + result = LogAndCreateTizenError(InvalidStateError, "Service is already started for the channel."); + } else { + ConvergenceChannel* channel = new ConvergenceChannel(channel_arg); // memory would be managed in Start method + const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); + + result = service->Start(channel, id); + } } //in case of failure call error callback, success callback will be triggered by listener @@ -474,11 +480,17 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceSend(const picoj result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); } else { // Running the service send procedure - ConvergenceChannel channel(ConvergenceUtils::GetArg(args, kJSArgumentChannel)); - ConvergencePayloadArray payload(ConvergenceUtils::GetArg(args, kJSArgumentPayload)); - const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); + auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); + std::vector::iterator channel_it = service->GetChannel(channel_arg); + + if (!service->IsChannelStarted(channel_it)) { + result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel."); + } else { + ConvergencePayloadArray payload(ConvergenceUtils::GetArg(args, kJSArgumentPayload)); + const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); - result = service->Send(channel, payload, id); + result = service->Send(*channel_it, payload, id); + } } //in case of failure call error callback, success callback will be triggered by listener @@ -517,10 +529,19 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceStop(const picoj result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); } else { // Running the service stop procedure - ConvergenceChannel channel(ConvergenceUtils::GetArg(args, kJSArgumentChannel)); - const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); - - result = service->Stop(channel, id); + auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); + std::vector::iterator channel_it = service->GetChannel(channel_arg); + + if (!service->IsChannelStarted(channel_it)) { + result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel."); + } else { + const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); + + result = service->Stop(*channel_it, id); + if (result) { + service->RemoveChannel(channel_it); + } + } } //in case of failure call error callback, success callback will be triggered by listener @@ -559,11 +580,22 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceGetClientList(co result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); } else { // Running the service getClientList procedure - ConvergenceChannel channel(ConvergenceUtils::GetArg(args, kJSArgumentChannel)); - result = service->GetClientList(channel, static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); + auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); + std::vector::iterator channel_it = service->GetChannel(channel_arg); + + if (!service->IsChannelStarted(channel_it)) { + result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel."); + } else { + const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); + + result = service->GetClientList(*channel_it, id); + } } - this->Post(token, result); + //in case of failure call error callback, success callback will be triggered by listener + if (!result) { + this->Post(token, result); + } }; std::thread(get_client_list, token).detach(); diff --git a/src/convergence/convergence_service.cc b/src/convergence/convergence_service.cc index 7c5fc62..61d9d3b 100644 --- a/src/convergence/convergence_service.cc +++ b/src/convergence/convergence_service.cc @@ -32,6 +32,7 @@ namespace { static const std::string kServiceType = "serviceType"; static const std::string kServiceConnectionState = "connectionState"; static const std::string kId = "id"; +static const std::string kUri = "uri"; static const std::string kVersion = "version"; } // namespace @@ -59,7 +60,7 @@ ConvergenceService::~ConvergenceService() { if (CONV_ERROR_NONE != error) { LoggerW("unset_listener error %d [%s]", error, get_error_message(error)); } else { - LoggerD("listener usnet"); + LoggerD("listener unset"); } std::for_each(opened_channels.begin(), opened_channels.end(), @@ -70,6 +71,7 @@ ConvergenceService::~ConvergenceService() { } else { LoggerD("2 service stopped"); } + delete c; }); // later destroy handle @@ -186,5 +188,32 @@ picojson::value ConvergenceService::ToJson() const { return picojson::value(service_json); } +std::vector::iterator ConvergenceService::GetChannel(const picojson::value &channel_json) { + ScopeLogger(); + + std::vector::iterator it; + const auto id = channel_json.get(kId).get(); + const auto uri = channel_json.get(kUri).get(); + + for (it = opened_channels.begin(); it != opened_channels.end(); ++it) { + if((*it)->GetUri() == uri && (*it)->GetId() == id) { + LoggerD("Found channel uri: [%s] id: [%s]", uri.c_str(), id.c_str()); + break; + } + } + + return it; +} + +bool ConvergenceService::IsChannelStarted(std::vector::iterator it) { + ScopeLogger(); + return it != opened_channels.end(); +} + +void ConvergenceService::RemoveChannel(std::vector::iterator it) { + ScopeLogger(); + opened_channels.erase(it); +} + } // namespace convergence } // namespace extension diff --git a/src/convergence/convergence_service.h b/src/convergence/convergence_service.h index 737debd..42ff0a6 100644 --- a/src/convergence/convergence_service.h +++ b/src/convergence/convergence_service.h @@ -45,6 +45,9 @@ class ConvergenceService { public: void Refresh(); + std::vector::iterator GetChannel(const picojson::value &channel_json); + bool IsChannelStarted(std::vector::iterator); + void RemoveChannel(std::vector::iterator); public: //conv_service_e get_type() const { return type_; } -- 2.7.4 From 7b3da85eb5cfcde5b214385ef367d07cdfb58938 Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Sun, 27 Nov 2016 15:31:13 +0900 Subject: [PATCH 02/16] [Convergence] Fixed ClientInfo in JS layer. [Verification] Code compiles. Change-Id: Iaaa100eaeff4a48e45eba3688f96cd22c244ede6 Signed-off-by: Tomasz Marciniak --- src/convergence/convergence_api.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index a61c8c3..1013663 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -678,15 +678,10 @@ native_.addListener('APP_COMMUNICATION_SERVICE_LISTENER', function(result) { case 'onRead': var clients_array = []; - for(var i = 0; i < result.payload.length; i++) { if (result.payload[i].key === 'client_list') { var value = JSON.parse(result.payload[i].value); - var client = new ClientInfo( - converter_.toBoolean(value.isHost, false), - converter_.toString(value.clientId, false), - converter_.toLong(value.connectTime, false) - ); + var client = new ClientInfo(value); clients_array.push(client); } } @@ -703,15 +698,6 @@ native_.addListener('APP_COMMUNICATION_SERVICE_LISTENER', function(result) { console.log('Ignoring result type: [' + result_type + ']'); break; } - - /* - // TODO uncomment when implemented (or remove thid data from the protocol) - *var clientInfo = new ClientInfo( - result.clientInfo.isHost, - result.clientInfo.lientId, - result.clientInfo.connectionTime);* - var clientInfo = null; - */ } }); @@ -1086,11 +1072,25 @@ function ChannelInfo(uri_, id_) { }); } -function ClientInfo(isHost, clientId, connectionTime) { +function ClientInfo(data) { validator_.isConstructorCall(this, ClientInfo); - this.isHost = isHost; - this.clientId = clientId; - this.connectionTime = connectionTime; + Object.defineProperties(this, { + isHost: { + value: converter_.toBoolean(data.isHost), + writable: false, + enumerable: true + }, + clientId: { + value: converter_.toString(data.clientId), + writable: false, + enumerable: true + }, + connectionTime: { + value: converter_.toLong(data.connectTime), + writable: false, + enumerable: true + } + }); } exports = new ConvergenceManager(); -- 2.7.4 From fb711ac747f8b6f88b588bc8c9ce6ca1072f4895 Mon Sep 17 00:00:00 2001 From: Lukasz Bardeli Date: Sun, 27 Nov 2016 15:18:11 +0100 Subject: [PATCH 03/16] [Convergance] refactoring throw InvalidStateError Change-Id: Ibc226f1fe694abc0bdb4740fb58198060df33753 Signed-off-by: Lukasz Bardeli --- src/convergence/convergence_api.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index 2e06968..ab9bf66 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -341,8 +341,9 @@ RemoteAppControlService.prototype.connect = function(successCallback, errorCallb } ]); - if (this.connectionState == ConnectionState.CONNECTED) - throw new WebAPIException('InvalidStateError', 'Service is connected already.'); + if (this.connectionState == ConnectionState.CONNECTED) { + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is connected already.'); + } var lid = this._serviceId; this._connectCallback = successCallback; @@ -380,7 +381,7 @@ RemoteAppControlService.prototype.disconnect = function(successCallback, errorCa ]); if (this.connectionState != ConnectionState.CONNECTED) { - throw new WebAPIException('InvalidStateError', 'Service is not connected yet.'); + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is not connected yet.'); } var result = native_.call('RemoteAppControlService_disconnect', { -- 2.7.4 From 4c0fc4a78fa66e0f517c14d51e8382139d71c449 Mon Sep 17 00:00:00 2001 From: "taekeun.kang" Date: Fri, 25 Nov 2016 17:45:27 +0900 Subject: [PATCH 04/16] [Push] Set empty string to optional attributes of PushMessage Change-Id: I516c5106de028bf8f95683573b73ba9fce4a1ebd Signed-off-by: taekeun.kang --- src/push/push_manager.cc | 4 ++ src/push/push_manager_common.cc | 86 ++++++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/push/push_manager.cc b/src/push/push_manager.cc index 467e091..84ec17a 100644 --- a/src/push/push_manager.cc +++ b/src/push/push_manager.cc @@ -283,6 +283,10 @@ common::PlatformResult PushManager::getRegistrationId(std::string& id) { common::PlatformResult PushManager::getUnreadNotifications() { LoggerD("Enter"); + if (!m_handle) { + return LogAndCreateResult(ErrorCode::SERVICE_NOT_AVAILABLE_ERR, "Not connected with push service"); + } + int ret = push_service_request_unread_notification(m_handle); if (PUSH_SERVICE_ERROR_NONE != ret) { return LogAndCreateResult(PushManagerCommon::ConvertPushError_2_4(ret), "Failed to get unread notifications", diff --git a/src/push/push_manager_common.cc b/src/push/push_manager_common.cc index 5be62da..863583e 100644 --- a/src/push/push_manager_common.cc +++ b/src/push/push_manager_common.cc @@ -65,32 +65,43 @@ void PushManagerCommon::notificationToJson(push_service_notification_h noti, pic char* temp = nullptr; int ret = push_service_get_notification_data(noti, &temp); if (ret != PUSH_SERVICE_ERROR_NONE) { - LoggerE("Failed to get appData"); - return; + if (ret == PUSH_SERVICE_ERROR_NO_DATA) { + LoggerI("push_service_get_notification_data return PUSH_SERVICE_ERROR_NO_DATA"); + (*obj)["appData"] = picojson::value(""); + } else { + LoggerE("Failed to get appData"); + return; + } + } else { + (*obj)["appData"] = picojson::value(temp); + free(temp); } - (*obj)["appData"] = picojson::value(temp); - free(temp); char* fullMessage = nullptr; ret = push_service_get_notification_message(noti, &fullMessage); if (ret != PUSH_SERVICE_ERROR_NONE) { - LoggerE("Failed to get message"); - return; - } - (*obj)["message"] = picojson::value(fullMessage); - - // parse query string and find value for alertMessage - pcrecpp::StringPiece input(fullMessage); - pcrecpp::RE re("([^=]+)=([^&]*)&?"); - string key; - string value; - while (re.Consume(&input, &key, &value)) { - if (key == "alertMessage") { - (*obj)["alertMessage"] = picojson::value(value); - break; + if (ret == PUSH_SERVICE_ERROR_NO_DATA) { + LoggerI("push_service_get_notification_message return PUSH_SERVICE_ERROR_NO_DATA"); + (*obj)["message"] = picojson::value(""); + } else { + LoggerE("Failed to get message"); + return; + } + } else { + (*obj)["message"] = picojson::value(fullMessage); + // parse query string and find value for alertMessage + pcrecpp::StringPiece input(fullMessage); + pcrecpp::RE re("([^=]+)=([^&]*)&?"); + string key; + string value; + while (re.Consume(&input, &key, &value)) { + if (key == "alertMessage") { + (*obj)["alertMessage"] = picojson::value(value); + break; + } } + free(fullMessage); } - free(fullMessage); long long int date = -1; ret = push_service_get_notification_time(noti, &date); @@ -102,20 +113,31 @@ void PushManagerCommon::notificationToJson(push_service_notification_h noti, pic ret = push_service_get_notification_sender(noti, &temp); if (ret != PUSH_SERVICE_ERROR_NONE) { - LoggerE("Failed to get sender"); - return; + if (ret == PUSH_SERVICE_ERROR_NO_DATA) { + LoggerI("push_service_get_notification_sender return PUSH_SERVICE_ERROR_NO_DATA"); + (*obj)["sender"] = picojson::value(""); + } else { + LoggerE("Failed to get sender"); + return; + } + } else { + (*obj)["sender"] = picojson::value(temp); + free(temp); } - (*obj)["sender"] = picojson::value(temp); - free(temp); ret = push_service_get_notification_session_info(noti, &temp); if (ret != PUSH_SERVICE_ERROR_NONE) { - LoggerE("Failed to get session info"); - return; + if (ret == PUSH_SERVICE_ERROR_NO_DATA) { + LoggerI("push_service_get_notification_session_info return PUSH_SERVICE_ERROR_NO_DATA"); + (*obj)["sessionInfo"] = picojson::value(""); + } else { + LoggerE("Failed to get session info"); + return; + } + } else { + (*obj)["sessionInfo"] = picojson::value(temp); + free(temp); } - std::string session_info = temp; - (*obj)["sesionInfo"] = picojson::value(temp); - free(temp); ret = push_service_get_notification_request_id(noti, &temp); if (ret != PUSH_SERVICE_ERROR_NONE) { @@ -124,14 +146,6 @@ void PushManagerCommon::notificationToJson(push_service_notification_h noti, pic } (*obj)["requestId"] = picojson::value(temp); free(temp); - - int type; - ret = push_service_get_notification_type(noti, &type); - if (ret != PUSH_SERVICE_ERROR_NONE) { - LoggerE("Failed to get type"); - return; - } - (*obj)["type"] = picojson::value(static_cast(type)); } // 3.0 version errors mappings -- 2.7.4 From 94c6968009c919ae3e5a5283e471214da25c95bd Mon Sep 17 00:00:00 2001 From: Hyunjin Park Date: Mon, 28 Nov 2016 18:45:36 +0900 Subject: [PATCH 05/16] [TM2] disable feature for 64bit binary - telephony (target : false, emul : true) - fm radio (target : false, emul : true) - secure element (target : false, emul : false) - NFC (target : false, emul : true) - no change [verification] so files are checked on 64bit emul and tm2 binary Change-Id: Ibbe84d951666d3ebe2c6ffba419983309999ed52 --- packaging/webapi-plugins.spec | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec index 86f279b..361b04c 100644 --- a/packaging/webapi-plugins.spec +++ b/packaging/webapi-plugins.spec @@ -10,7 +10,7 @@ %define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions} Name: webapi-plugins -Version: 1.51 +Version: 1.52 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries @@ -25,6 +25,14 @@ Source0: %{name}-%{version}.tar.gz %define tizen_is_emulator 1 %endif +%if "%{_repository}" == "arm64-wayland" +# 64bit +%define tizen_is_arm64 1 +%else +# 32bit +%define tizen_is_arm64 0 +%endif + #################################################################### # Common Profile : artik # #################################################################### @@ -84,7 +92,8 @@ Source0: %{name}-%{version}.tar.gz %endif # tizen_profile_common #################################################################### -# Mobile Profile : TM1, Redwood(SM-Z910F), KIRAN(Z130H) # +# Mobile Profile : TM1(32bit), Redwood(SM-Z910F), KIRAN(Z130H) # +# TM2(64bit) #################################################################### %if "%{?profile}" == "mobile" @@ -111,7 +120,18 @@ Source0: %{name}-%{version}.tar.gz %define tizen_feature_exif_support 1 %define tizen_feature_feedback_support 1 %define tizen_feature_filesystem_support 1 + +# FM radio feature +%if 0%{?tizen_is_emulator} %define tizen_feature_fm_radio_support 1 +%else +%if 0%{?tizen_is_arm64} +%define tizen_feature_fm_radio_support 0 +%else +%define tizen_feature_fm_radio_support 1 +%endif +%endif + %if 0%{?tizen_is_emulator} %define tizen_feature_ham_support 1 %else @@ -142,16 +162,34 @@ Source0: %{name}-%{version}.tar.gz %define tizen_feature_power_support 1 %define tizen_feature_preference_support 1 %define tizen_feature_push_support 1 + +# secure element feature %if 0%{?tizen_is_emulator} %define tizen_feature_se_support 0 %else +%if 0%{?tizen_is_arm64} +%define tizen_feature_se_support 0 +%else %define tizen_feature_se_support 1 %endif +%endif + %define tizen_feature_sensor_support 1 %define tizen_feature_sound_support 1 %define tizen_feature_system_info_support 1 %define tizen_feature_system_setting_support 1 + +# telephony feature +%if 0%{?tizen_is_emulator} %define tizen_feature_telephony_support 1 +%else +%if 0%{?tizen_is_arm64} +%define tizen_feature_telephony_support 0 +%else +%define tizen_feature_telephony_support 1 +%endif +%endif + %define tizen_feature_time_support 1 %define tizen_feature_web_setting_support 1 %define tizen_feature_widget_service_support 1 -- 2.7.4 From 6c9ad016cfce16b50890866308f44c31cea8c1fe Mon Sep 17 00:00:00 2001 From: "taekeun.kang" Date: Wed, 23 Nov 2016 10:21:33 +0900 Subject: [PATCH 06/16] [Convergence] Fix error handling codes to satisfy spec. Change-Id: Ic829ccab2bd4702cd7eb4ff06082c019e6a74dff Signed-off-by: taekeun.kang --- src/convergence/convergence_api.js | 33 ++++++++---- .../convergence_app_communication_service.cc | 35 +++++-------- src/convergence/convergence_instance.cc | 59 +++++++++++++++------- src/convergence/convergence_manager.cc | 11 ++-- .../convergence_remote_app_control_service.cc | 22 +++----- src/convergence/convergence_utils.cc | 25 ++++++++- src/convergence/convergence_utils.h | 3 +- 7 files changed, 114 insertions(+), 74 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index ab9bf66..faa26b4 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -124,7 +124,7 @@ ConvergenceManager.prototype.startDiscovery = function(successCallback, console.log('Entered ConvergenceManager.startDiscovery()'); if (discoveryStarted) - throw new WebAPIException('InvalidStateError', 'Discovery has been started.'); + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Discovery has been started.'); var args = validator_.validateArgs(arguments, [ {name: 'successCallback', type: types_.LISTENER, values: ['onfound', 'onfinished' ]}, @@ -133,6 +133,9 @@ ConvergenceManager.prototype.startDiscovery = function(successCallback, ]); // Indicate, that discovery procedure is on + if (discoveryStarted === true) + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Discovery has already started.'); + discoveryStarted = true; // Reset currently available device list @@ -185,6 +188,9 @@ ConvergenceManager.prototype.startDiscovery = function(successCallback, native_.callIfPossible(successCallback.onfound, d); } else if (result.discovery_status == 'discovery_finished') { + + discoveryStarted = false; + // Unregister discovery listener, because Convergence Manager is a // singleton object and no one else can receive discovery results native_.removeListener('CONVERGENCE_DISCOVERY_LISTENER'); @@ -208,7 +214,9 @@ ConvergenceManager.prototype.startDiscovery = function(successCallback, native_.callIfPossible(errorCallback, native_.getErrorObject(result)); } }); + if (native_.isFailure(result)) { + discoveryStarted = false; throw native_.getErrorObject(result); } }; @@ -216,8 +224,8 @@ ConvergenceManager.prototype.startDiscovery = function(successCallback, ConvergenceManager.prototype.stopDiscovery = function() { console.log('Entered ConvergenceManager.stopDiscovery()'); - if (!discoveryStarted) - throw new WebAPIException('InvalidStateError', 'Discovery has not started yet.'); + if (discoveryStarted === false) + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Discovery has not started yet.'); discoveryStarted = false; @@ -341,7 +349,7 @@ RemoteAppControlService.prototype.connect = function(successCallback, errorCallb } ]); - if (this.connectionState == ConnectionState.CONNECTED) { + if (this.connectionState === ConnectionState.CONNECTED) { throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is connected already.'); } @@ -356,6 +364,7 @@ RemoteAppControlService.prototype.connect = function(successCallback, errorCallb if (native_.isFailure(result)) native_.callIfPossible(errorCallback, native_.getErrorObject(result)); }); + if (native_.isFailure(result)) throw native_.getErrorObject(result); }; @@ -380,7 +389,7 @@ RemoteAppControlService.prototype.disconnect = function(successCallback, errorCa } ]); - if (this.connectionState != ConnectionState.CONNECTED) { + if (this.connectionState !== ConnectionState.CONNECTED) { throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is not connected yet.'); } @@ -414,10 +423,10 @@ RemoteAppControlService.prototype.start = function() { nullable: true }]); -/* - if (this.serviceState == ConnectionState.CONNECTED) - throw new WebAPIException('InvalidStateError', 'Service is connected already.'); -*/ + + if (this.connectionState === ConnectionState.NOT_CONNECTED) { + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is not connected yet.'); + } var lid = this._serviceId; this._startCallback = args.successCallback; @@ -905,6 +914,7 @@ AppCommunicationService.prototype.setListener = function(listenerCallback) { deviceId: this._deviceId, curListenerId: lid }); + if (native_.isFailure(result)) throw native_.getErrorObject(result); @@ -921,6 +931,7 @@ AppCommunicationService.prototype.unsetListener = function(id) { deviceId: this._deviceId //curListenerId: id // not needed in below layers }); + if (native_.isFailure(result)) throw native_.getErrorObject(result); @@ -979,7 +990,7 @@ AppCommunicationClientService.prototype.connect = function(successCallback, erro ]); if (this.connectionState == ConnectionState.CONNECTED) - throw new WebAPIException('InvalidStateError', 'Service is connected already.'); + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is connected already.'); var lid = this._serviceId; this._connectCallback = successCallback; @@ -1018,7 +1029,7 @@ AppCommunicationClientService.prototype.disconnect = function(successCallback, e } ]); if (this.connectionState != ConnectionState.CONNECTED) - throw new WebAPIException('InvalidStateError', 'Service is not connected yet.'); + throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is not connected yet.'); var result = native_.call('AppCommunicationClientService_disconnect', { deviceId: this._deviceId diff --git a/src/convergence/convergence_app_communication_service.cc b/src/convergence/convergence_app_communication_service.cc index 41b8fca..42ce200 100644 --- a/src/convergence/convergence_app_communication_service.cc +++ b/src/convergence/convergence_app_communication_service.cc @@ -76,7 +76,7 @@ common::TizenResult ConvergenceAppCommunicationService::Start( const int error = conv_service_start(service_handle, channel->GetHandle(), nullptr); if (CONV_ERROR_NONE != error) { - return LogAndCreateTizenError(AbortError, "Failed to start service"); + return LogAndCreateTizenError(AbortError, "conv_service_start [fail]"); } opened_channels.push_back(ch_ptr.release()); @@ -113,8 +113,7 @@ common::TizenResult ConvergenceAppCommunicationService::GetClientList(Convergenc conv_service_h service_handle = FindServiceHandle(); if (!service_handle) { - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } UpdateListener(cur_listener_id); @@ -142,7 +141,7 @@ common::TizenResult ConvergenceAppCommunicationService::Send( const int error = conv_service_publish(service_handle, channel->GetHandle(), payload.GetHandle()); if (CONV_ERROR_NONE != error) { - return LogAndCreateTizenError(AbortError, "Failed to publish message"); + return LogAndCreateTizenError(AbortError, "conv_service_publish [fail]"); } else { LoggerI("PUBLISHED SUCCESSFULY listener is [%d]", cur_listener_id); } @@ -171,8 +170,7 @@ void ConvergenceAppCommunicationService::ServiceListenerCb(conv_service_h servic if (CONV_ERROR_NONE != error) { // Error occured during connection picojson::object param; - param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusError); - param[kServiceListenerError] = picojson::value(static_cast(error)); + param[kServiceListenerError] = LogAndCreateTizenError(AbortError, "DiscoveryCb return CONV_DISCOVERY_RESULT_ERROR").ToJSON(); callbackParam->plugin_->ReplyAsync(kAppCommunicationListenerCallback, callbackParam->callback_id_, false, param); return; @@ -274,9 +272,9 @@ void ConvergenceAppCommunicationService::UpdateListener(const int cur_listener_i common::TizenResult ConvergenceAppCommunicationService::SetListener(const int cur_listener_id) { ScopeLogger(); conv_service_h service_handle = FindServiceHandle(); - if (!service_handle) - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + if (!service_handle) { + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); + } UpdateListener(cur_listener_id); @@ -288,17 +286,12 @@ common::TizenResult ConvergenceAppCommunicationService::RemoveListener() { conv_service_h service_handle = FindServiceHandle(); if (!service_handle) { - LoggerE("AAAAAA!!! Service not found"); - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } const int error = conv_service_unset_listener_cb(service_handle); if (CONV_ERROR_NONE != error) { - // TODO: Handle error - trace_conv_error(error, __LINE__, "conv_service_set_listener_cb"); - return LogAndCreateTizenError(NotFoundError, - "Unset Listener Failed"); + return LogAndCreateTizenError(AbortError, "conv_service_unset_listener_cb [Fail]"); } return TizenSuccess(); @@ -449,8 +442,7 @@ common::TizenResult ConvergenceAppCommunicationClientService::Connect(const int conv_service_h service = FindServiceHandle(); if (!service) { - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service is NULL"); } // TODO: make a garbage collection and release this memory when service is disconnected @@ -462,6 +454,7 @@ common::TizenResult ConvergenceAppCommunicationClientService::Connect(const int if (CONV_ERROR_NONE != error) { // TODO: Handle error trace_conv_error(error, __LINE__, "conv_service_connect"); + return LogAndCreateTizenError(AbortError, "conv_service_connect [fail]"); } return TizenSuccess(); @@ -472,13 +465,13 @@ common::TizenResult ConvergenceAppCommunicationClientService::Disconnect() { conv_service_h service = FindServiceHandle(); if (!service) - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service is NULL"); const int error = conv_service_disconnect(service); if (CONV_ERROR_NONE != error) { // TODO: Handle error trace_conv_error(error, __LINE__, "conv_service_disconnect"); + return LogAndCreateTizenError(AbortError, "conv_service_disconnect [fail]"); } return TizenSuccess(); @@ -486,4 +479,4 @@ common::TizenResult ConvergenceAppCommunicationClientService::Disconnect() { } // namespace convergence -} // namespace extension +} // namespace extension diff --git a/src/convergence/convergence_instance.cc b/src/convergence/convergence_instance.cc index c905ee4..7e8dc0a 100644 --- a/src/convergence/convergence_instance.cc +++ b/src/convergence/convergence_instance.cc @@ -204,7 +204,8 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceConnect(const pi 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"); + result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } else { // Running the service connect procedure result = service->Connect(static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); @@ -237,7 +238,8 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceDisconnect(const 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"); + result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } else { result = service->Disconnect(); } @@ -273,7 +275,8 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceStart(const pico 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"); + result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } else { // Running the service start procedure result = service->Start(static_cast(ConvergenceUtils::GetArg(args, kJSArgumentReply).get()), @@ -311,7 +314,8 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceStop(const picoj 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"); + result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } else { // Running the service stop procedure result = service->Stop(static_cast(ConvergenceUtils::GetArg(args, kJSArgumentReply).get()), @@ -349,7 +353,8 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunch(const pic 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"); + result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } else { result = service->Launch( ConvergenceUtils::GetArg(args, kJSArgumentAppId).to_str().c_str(), @@ -389,7 +394,8 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunchAppControl 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"); + result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } else { result = service->LaunchAppControl(ConvergenceUtils::GetArg(args, kJSArgumentAppControl).get(), ConvergenceUtils::GetArg(args, kJSArgumentAppId).to_str().c_str(), @@ -427,14 +433,16 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceStart(const pico ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + result = LogAndCreateTizenError(AbortError, "Service is NULL", + ("Service is NULL")); } else { // Running the service start procedure auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); std::vector::iterator channel_it = service->GetChannel(channel_arg); if (service->IsChannelStarted(channel_it)) { - result = LogAndCreateTizenError(InvalidStateError, "Service is already started for the channel."); + result = LogAndCreateTizenError(InvalidStateError, "Service is already started for the channel.", + ("Service is already started for the channel.")); } else { ConvergenceChannel* channel = new ConvergenceChannel(channel_arg); // memory would be managed in Start method const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); @@ -477,14 +485,16 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceSend(const picoj ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + result = LogAndCreateTizenError(AbortError, "service is NULL", + ("service is NULL")); } else { // Running the service send procedure auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); std::vector::iterator channel_it = service->GetChannel(channel_arg); if (!service->IsChannelStarted(channel_it)) { - result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel."); + result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel.", + ("Service is not started for the channel.")); } else { ConvergencePayloadArray payload(ConvergenceUtils::GetArg(args, kJSArgumentPayload)); const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); @@ -526,14 +536,16 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceStop(const picoj ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + result = LogAndCreateTizenError(AbortError, "Service is NULL", + ("Service is NULL")); } else { // Running the service stop procedure auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); std::vector::iterator channel_it = service->GetChannel(channel_arg); if (!service->IsChannelStarted(channel_it)) { - result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel."); + result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel.", + ("Service is not started for the channel.")); } else { const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); @@ -577,14 +589,16 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceGetClientList(co ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } else { // Running the service getClientList procedure auto channel_arg = ConvergenceUtils::GetArg(args, kJSArgumentChannel); std::vector::iterator channel_it = service->GetChannel(channel_arg); if (!service->IsChannelStarted(channel_it)) { - result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel."); + result = LogAndCreateTizenError(InvalidStateError, "Service is not started for the channel.", + ("Service is not started for the channel.")); } else { const int id = static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get()); @@ -618,7 +632,8 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceSetListener(cons ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - LogAndReturnTizenError(common::NotFoundError("Can not find the service type = 1")); + return LogAndCreateTizenError(AbortError, "service is NULL", + ("service is NULL")); } // Running the service stop procedure @@ -640,7 +655,8 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceUnsetListener(co ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - LogAndReturnTizenError(common::NotFoundError("Can not find the service type = 1")); + return LogAndCreateTizenError(AbortError, "service is NULL", + ("service is NULL")); } // Running the service stop procedure @@ -658,7 +674,8 @@ common::TizenResult ConvergenceInstance::AppCommunicationServerServiceConstructL ConvergenceManager::GetInstance(this).RegisterLocalService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - LogAndReturnTizenError(common::NotFoundError("Can not find the service type = 1")); + return LogAndCreateTizenError(AbortError, "Can not find the service type = 1", + ("Can not find the service type = 1")); } return common::TizenSuccess(); @@ -667,6 +684,8 @@ common::TizenResult ConvergenceInstance::AppCommunicationServerServiceConstructL common::TizenResult ConvergenceInstance::AppCommunicationClientServiceConnect(const picojson::object& args, const common::AsyncToken& token) { ScopeLogger(); + + // [TK] SecurityError CHECK_PRIVILEGE(kPrivilegeInternet); CHECK_PRIVILEGE(kPrivilegeBluetooth); @@ -685,7 +704,8 @@ common::TizenResult ConvergenceInstance::AppCommunicationClientServiceConnect(co ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + result = LogAndCreateTizenError(AbortError, "Service is NULL", + ("service is NULL")); } else { // Running the service connect procedure result = service->Connect(static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); @@ -717,7 +737,8 @@ common::TizenResult ConvergenceInstance::AppCommunicationClientServiceDisconnect ConvergenceManager::GetInstance(this).GetService(ConvergenceUtils::GetArg(args, kJSArgumentDeviceId).to_str().c_str(), CONV_SERVICE_APP_TO_APP_COMMUNICATION)); if (!service) { - result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1"); + result = LogAndCreateTizenError(AbortError, "Service is NULL", + ("Service is NULL")); } else { // Running the service disconnect procedure result = service->Disconnect(); diff --git a/src/convergence/convergence_manager.cc b/src/convergence/convergence_manager.cc index e7ae08f..c7f6784 100644 --- a/src/convergence/convergence_manager.cc +++ b/src/convergence/convergence_manager.cc @@ -41,7 +41,7 @@ static const std::string kDiscoveryStatus = "discovery_status"; static const std::string kDiscoveryStatusDeviceFound = "device_found"; static const std::string kDiscoveryStatusFinished = "discovery_finished"; static const std::string kDiscoveryStatusError = "discovery_error"; -static const std::string kDiscoveryError = "discovery_error"; +static const std::string kDiscoveryError = "error"; } // namespace @@ -185,8 +185,7 @@ void ConvergenceManager::DiscoveryCb(conv_device_h device_handle, case CONV_DISCOVERY_RESULT_ERROR: { LoggerE("Discovery Error"); picojson::object param; - param[kDiscoveryStatus] = picojson::value(kDiscoveryStatusError); - param[kDiscoveryError] = picojson::value(static_cast(result)); + param[kDiscoveryError] = LogAndCreateTizenError(AbortError, "DiscoveryCb return CONV_DISCOVERY_RESULT_ERROR").ToJSON(); owner->convergence_plugin_->ReplyAsync(kConvergenceManagerDiscoveryCallback, -1, false, @@ -205,8 +204,7 @@ TizenResult ConvergenceManager::StartDiscovery(long timeout) { const int error = conv_discovery_start(convergence_manager_, (const int)timeout, DiscoveryCb, this); if (CONV_ERROR_NONE != error) { - // TODO: Handle error - trace_conv_error(error, __LINE__, "conv_discovery_start"); + return LogAndCreateTizenError(AbortError, "conv_discovery_start [fail]"); } return TizenSuccess(); } @@ -215,8 +213,7 @@ TizenResult ConvergenceManager::StopDiscovery() { ScopeLogger(); const int error = conv_discovery_stop(convergence_manager_); if (CONV_ERROR_NONE != error) { - // TODO: Handle error - trace_conv_error(error, __LINE__, "conv_discovery_stop"); + return LogAndCreateTizenError(AbortError, "conv_discovery_stop [fail]"); } return TizenSuccess(); } diff --git a/src/convergence/convergence_remote_app_control_service.cc b/src/convergence/convergence_remote_app_control_service.cc index c957e63..c0ec611 100644 --- a/src/convergence/convergence_remote_app_control_service.cc +++ b/src/convergence/convergence_remote_app_control_service.cc @@ -98,17 +98,14 @@ TizenResult ConvergenceRemoteAppControlService::Connect(const int cur_listener_i conv_service_h service = FindServiceHandle(); if (!service) { - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } CallbackParam *param = new CallbackParam(convergence_plugin_, cur_listener_id); const int error = conv_service_connect(service, ServiceConnectedCb, param); - if (CONV_ERROR_NONE != error) { - // TODO: Handle error delete param; - trace_conv_error(error, __LINE__, "conv_service_connect"); + return LogAndCreateTizenError(AbortError, "conv_service_connect [Fail]"); } else { // Hopefully we are sure that the service is disconnected connect_callback_param_ = param; @@ -123,14 +120,11 @@ TizenResult ConvergenceRemoteAppControlService::Disconnect() { conv_service_h service = FindServiceHandle(); if (!service) - return LogAndCreateTizenError(NotFoundError, - "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); const int error = conv_service_disconnect(service); - if (CONV_ERROR_NONE != error) { - // TODO: Handle error - trace_conv_error(error, __LINE__, "conv_service_disconnect"); + return LogAndCreateTizenError(AbortError, "conv_service_disconnect [Fail]"); } else { delete connect_callback_param_; connect_callback_param_ = nullptr; @@ -149,7 +143,7 @@ TizenResult ConvergenceRemoteAppControlService::Start(const bool reply, const in conv_service_h service = FindServiceHandle(); if (!service) { - return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } if (reply) { @@ -176,7 +170,7 @@ TizenResult ConvergenceRemoteAppControlService::Stop(const bool reply, const int conv_service_h service = FindServiceHandle(); if (!service) { - return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } if (reply) { @@ -275,7 +269,7 @@ TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool r conv_service_h service_handle = FindServiceHandle(); if (!service_handle) { - return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } int ret = conv_payload_create(&payload); @@ -351,7 +345,7 @@ TizenResult ConvergenceRemoteAppControlService::LaunchAppControl(const picojson: // Get service_handle conv_service_h service_handle = FindServiceHandle(); if (!service_handle) { - return LogAndCreateTizenError(NotFoundError, "Service with specified type does not exist"); + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } // Create payload diff --git a/src/convergence/convergence_utils.cc b/src/convergence/convergence_utils.cc index 525b428..bfc67b0 100644 --- a/src/convergence/convergence_utils.cc +++ b/src/convergence/convergence_utils.cc @@ -74,5 +74,28 @@ const picojson::value& ConvergenceUtils::GetArg(const picojson::object& args, co } } +common::TizenResult ConvergenceUtils::ConvertConvergenceError(int error) { + switch (error) { + case CONV_ERROR_NONE: + return common::TizenSuccess(); + case CONV_ERROR_INVALID_OPERATION: + case CONV_ERROR_PERMISSION_DENIED: // Never return + case CONV_ERROR_NOT_SUPPORTED: // Never return + case CONV_ERROR_INVALID_PARAMETER: // Never return + return common::InvalidStateError(error); + case CONV_ERROR_OUT_OF_MEMORY: + case CONV_ERROR_NO_DATA: + + // return common::IoError(error); + // return common::SecurityError(error); + // return common::NotSupportedError(error); + // return common::InvalidValuesError(error); + // return common::TimeoutError(error); + // return common::TypeMismatchError(error); + // return common::InvalidStateError(error); + return common::AbortError(error); + } +} + } // namespace convergence -} // namespace extension +} // namespace extension \ No newline at end of file diff --git a/src/convergence/convergence_utils.h b/src/convergence/convergence_utils.h index a7aa280..ab4570e 100644 --- a/src/convergence/convergence_utils.h +++ b/src/convergence/convergence_utils.h @@ -57,7 +57,7 @@ static const std::string kServiceConnectionStatusNotConnected = "service_not_con static const std::string kServiceListenerStatus = "listener_status"; static const std::string kServiceListenerStatusOk = "listener_ok"; static const std::string kServiceListenerStatusError = "listener_error"; -static const std::string kServiceListenerError = "listener_error"; +static const std::string kServiceListenerError = "error"; } // namespace struct CallbackParam { @@ -73,6 +73,7 @@ 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); + static common::TizenResult ConvertConvergenceError(int error); }; } // namespace convergence -- 2.7.4 From 15657622b75ba090667c2d3d19dfe549126d4275 Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Tue, 29 Nov 2016 09:02:59 +0900 Subject: [PATCH 07/16] [Convergence] Set readonly attributes for Service. [Verification] Code compiles. Change-Id: Ic0f96d60e8825d3d74098a87488f29d8a6e22342 Signed-off-by: Tomasz Marciniak --- src/convergence/convergence_api.js | 64 +++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index faa26b4..59e2d2d 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -68,6 +68,18 @@ function SetReadOnlyProperty(obj, n, v) { }); } +function InternalData(d) { + for (var prop in d) { + if (d.hasOwnProperty(prop)) { + this[prop] = d[prop]; + } + } +} + +function updateWithInternalData(src, dst) { + var d = new InternalData(src); + dst.connectionState = d; +} function getServiceConnectionStateName(connectionStateNumber) { switch(connectionStateNumber) { @@ -172,8 +184,9 @@ ConvergenceManager.prototype.startDiscovery = function(successCallback, continue; } - s.connectionState = getServiceConnectionStateName( - result.device.services[i].connectionState); + var state = getServiceConnectionStateName(result.device.services[i].connectionState); + updateWithInternalData({ connectionState: state }, s); + s._deviceId = id; services.push(s); } @@ -234,11 +247,29 @@ ConvergenceManager.prototype.stopDiscovery = function() { throw native_.getErrorObject(result); }; -function Service() { +function Service(connectionState_, type_) { console.log('Entered Service.constructor()'); - //validator_.isConstructorCall(this, Service); - this.connectionState = ConnectionState.NOT_CONNECTED; + var connectionState = connectionState_; + + Object.defineProperties(this, { + connectionState: { + enumerable: true, + get: function() { + return connectionState; + }, + set: function(v) { + if (v instanceof InternalData && v.hasOwnProperty('connectionState')) { + connectionState = v['connectionState']; + } + } + }, + type: { + value: type_, + writable: false, + enumerable: true + } + }) } native_.addListener('REMOTE_APP_CONTROL_SERVICE_LISTENER', function(result) { @@ -265,7 +296,7 @@ native_.addListener('REMOTE_APP_CONTROL_SERVICE_LISTENER', function(result) { switch (result_type) { case 'Connected': if (s) { // Service MUST NOT be null here - s.connectionState = ConnectionState.CONNECTED; + updateWithInternalData({ connectionState: ConnectionState.CONNECTED }, s); convergenceServices[lid] = s; } native_.callIfPossible(s._connectCallback, s); @@ -321,13 +352,14 @@ function RemoteAppControlService() { } }); - this.type = ServiceType.REMOTE_APP_CONTROL; + Service.call(this, ConnectionState.NOT_CONNECTED, ServiceType.REMOTE_APP_CONTROL); // Registering the service in the table of issued services convergenceServices[this._serviceId] = this; } RemoteAppControlService.prototype = new Service(); +RemoteAppControlService.prototype.constructor = RemoteAppControlService; RemoteAppControlService.prototype.connect = function(successCallback, errorCallback) { console.log('Entered RemoteAppControlService.connect()'); @@ -404,7 +436,7 @@ RemoteAppControlService.prototype.disconnect = function(successCallback, errorCa if (native_.isFailure(result)) { throw native_.getErrorObject(result); } else { - this.connectionState = ConnectionState.NOT_CONNECTED; + updateWithInternalData({ connectionState: ConnectionState.NOT_CONNECTED }, this); } native_.callIfPossible(successCallback, this); @@ -581,9 +613,10 @@ RemoteAppControlService.prototype.launchAppControl = function() { } }; -function AppCommunicationService() { +function AppCommunicationService(connectionState_, type_) { console.log('Entered AppCommunicationService.constructor()'); + Service.call(this, connectionState_, type_); // The device id is needed for getting the valid service handle on the // native layer // I have to implement this property here instead of base constructor in order @@ -640,6 +673,7 @@ function AppCommunicationService() { } AppCommunicationService.prototype = new Service(); +AppCommunicationService.prototype.constructor = AppCommunicationService; native_.addListener('APP_COMMUNICATION_SERVICE_LISTENER', function(result) { @@ -668,7 +702,7 @@ native_.addListener('APP_COMMUNICATION_SERVICE_LISTENER', function(result) { switch (result_type) { case 'Connected': if (s) { // Service MUST NOT be null here - s.connectionState = ConnectionState.CONNECTED; + updateWithInternalData({ connectionState: ConnectionState.CONNECTED }, s); convergenceServices[lid] = s; } native_.callIfPossible(s._connectCallback, s); @@ -948,8 +982,7 @@ function AppCommunicationServerService() { validator_.isConstructorCall(this, AppCommunicationServerService); - this.connectionState = ConnectionState.NOT_CONNECTED; - this.type = ServiceType.APP_COMM_SERVER; + AppCommunicationService.call(this, ConnectionState.NOT_CONNECTED, ServiceType.APP_COMM_SERVER); native_.callSync('AppCommunicationServerService_constructLocal', { deviceId: this._deviceId @@ -957,17 +990,18 @@ function AppCommunicationServerService() { } AppCommunicationServerService.prototype = new AppCommunicationService(); +AppCommunicationServerService.prototype.constructor = AppCommunicationServerService; function AppCommunicationClientService() { console.log('Entered AppCommunicationClientService.constructor()'); validator_.isConstructorCall(this, AppCommunicationClientService); - this.connectionState = ConnectionState.NOT_CONNECTED; - this.type = ServiceType.APP_COMM_CLIENT; + AppCommunicationService.call(this, ConnectionState.NOT_CONNECTED, ServiceType.APP_COMM_CLIENT); } AppCommunicationClientService.prototype = new AppCommunicationService(); +AppCommunicationClientService.prototype.constructor = AppCommunicationClientService; AppCommunicationClientService.prototype.connect = function(successCallback, errorCallback) { console.log('Entered AppCommunicationClientService.connect()'); @@ -1042,7 +1076,7 @@ AppCommunicationClientService.prototype.disconnect = function(successCallback, e if (native_.isFailure(result)) { throw native_.getErrorObject(result); } else { - this.connectionState = ConnectionState.NOT_CONNECTED; + updateWithInternalData({ connectionState: ConnectionState.NOT_CONNECTED }, this); } native_.callIfPossible(successCallback, this); -- 2.7.4 From 4c95f7e1b4b33a603470f14e63c01bb5671241a1 Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Tue, 29 Nov 2016 14:07:13 +0100 Subject: [PATCH 08/16] [TVInputDevice] Register/unregister keys from mandatoryMap This commit introduce following changes to TVInputDevice API: * list keys from mandatoryMap with getSupportedKeys * register and unregister a single key from mandatoryMap * register and unregister a batch of keys from mandatoryMap Change-Id: I78ce888e8501fb245e5136f574c40d34f5907da3 Signed-off-by: Pawel Wasowski --- src/tvinputdevice/tvinputdevice_api.js | 37 +++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/tvinputdevice/tvinputdevice_api.js b/src/tvinputdevice/tvinputdevice_api.js index b2f34f1..94af452 100755 --- a/src/tvinputdevice/tvinputdevice_api.js +++ b/src/tvinputdevice/tvinputdevice_api.js @@ -266,7 +266,11 @@ TVInputDeviceManager.prototype.getSupportedKeys = function() { re.push(new TVInputDeviceKey({name: key, code: map[key].keyCode})); } } - + for (var key in mandatoryMap) { + if (mandatoryMap.hasOwnProperty(key)) { + re.push(new TVInputDeviceKey({name: key, code: mandatoryMap[key].keyCode})); + } + } return re; }; @@ -303,12 +307,16 @@ TVInputDeviceManager.prototype.registerKey = function(keyName) { var args = validator.validateArgs(arguments, [ {name: 'keyName', type: types.STRING} ]); - if (!map[args.keyName]) { + if (!map[args.keyName] && !mandatoryMap[args.keyName]) { throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Parameter "keyName" is invalid.'); } - var ret = native.sendRuntimeSyncMessage('tizen://api/inputdevice/registerKey', map[args.keyName].keyName); + if (map[args.keyName]) { + var ret = native.sendRuntimeSyncMessage('tizen://api/inputdevice/registerKey', map[args.keyName].keyName); + } else { + var ret = native.sendRuntimeSyncMessage('tizen://api/inputdevice/registerKey', mandatoryMap[args.keyName].keyName); + } if (ret === 'error') { throw new WebAPIException(WebAPIException.UNKNOWN_ERR, 'UnknownError'); } @@ -324,13 +332,16 @@ TVInputDeviceManager.prototype.unregisterKey = function(keyName) { var args = validator.validateArgs(arguments, [ {name: 'keyName', type: types.STRING} ]); - - if (!map[args.keyName]) { + if (!map[args.keyName] && !mandatoryMap[args.keyName]) { throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Parameter "keyName" is invalid.'); } - var ret = native.sendRuntimeSyncMessage('tizen://api/inputdevice/unregisterKey', map[args.keyName].keyName); + if (map[args.keyName]) { + var ret = native.sendRuntimeSyncMessage('tizen://api/inputdevice/unregisterKey', map[args.keyName].keyName); + } else { + var ret = native.sendRuntimeSyncMessage('tizen://api/inputdevice/unregisterKey', mandatoryMap[args.keyName].keyName); + } if (ret === 'error') { throw new WebAPIException(WebAPIException.UNKNOWN_ERR, 'UnknownError'); } @@ -360,11 +371,14 @@ TVInputDeviceManager.prototype.registerKeyBatch = function() { var keysList = ""; for (var i = 0; i < args.keyNames.length; ++i) { - if (!map[args.keyNames[i]]) { + if (map[args.keyNames[i]]) { + keysList += map[args.keyNames[i]].keyName + ((i < args.keyNames.length - 1) ? "," : ""); + } else if (mandatoryMap[args.keyNames[i]]) { + keysList += mandatoryMap[args.keyNames[i]].keyName + ((i < args.keyNames.length - 1) ? "," : ""); + } else { throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid key name: "' + args.keyNames[i] + '"'); } - keysList += map[args.keyNames[i]].keyName + ((i < args.keyNames.length - 1) ? "," : ""); } setTimeout(function() { @@ -402,11 +416,14 @@ TVInputDeviceManager.prototype.registerKeyBatch = function() { var keysList = ""; for (var i = 0; i < args.keyNames.length; ++i) { - if (!map[args.keyNames[i]]) { + if (map[args.keyNames[i]]) { + keysList += map[args.keyNames[i]].keyName + ((i < args.keyNames.length - 1) ? "," : ""); + } else if (mandatoryMap[args.keyNames[i]]) { + keysList += mandatoryMap[args.keyNames[i]].keyName + ((i < args.keyNames.length - 1) ? "," : ""); + } else { throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Invalid key name: "' + args.keyNames[i] + '"'); } - keysList += map[args.keyNames[i]].keyName + ((i < args.keyNames.length - 1) ? "," : ""); } setTimeout(function() { -- 2.7.4 From 1ef5d8298ac168c134efa67ad904035fa8c175a8 Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Tue, 29 Nov 2016 17:42:17 +0900 Subject: [PATCH 09/16] [Convergence] Some fixes for RemoteAppControlService. [Verification] Code compiles. Change-Id: I7bb1b979731153512fed0287c9290f490efc312f Signed-off-by: Tomasz Marciniak --- src/convergence/convergence_api.js | 13 ++------ src/convergence/convergence_instance.cc | 38 ++++++++++++++-------- .../convergence_remote_app_control_service.cc | 9 ++--- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index 59e2d2d..81718f5 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -368,14 +368,12 @@ RemoteAppControlService.prototype.connect = function(successCallback, errorCallb { name: 'successCallback', type: types_.FUNCTION, - //values: ConnectSuccessCallback, optional: false, nullable: false }, { name: 'errorCallback', type: types_.FUNCTION, - //values: ErrorCallback, optional: true, nullable: true } @@ -408,14 +406,12 @@ RemoteAppControlService.prototype.disconnect = function(successCallback, errorCa { name: 'successCallback', type: types_.FUNCTION, - //values: ConnectSuccessCallback, optional: true, nullable: true }, { name: 'errorCallback', type: types_.FUNCTION, - //values: ErrorCallback, optional: true, nullable: true } @@ -520,23 +516,19 @@ RemoteAppControlService.prototype.launch = function(appId, successCallback, erro var args = validator_.validateArgs(arguments, [ { name: 'appId', - //type: types_.PLATFORM_OBJECT, type: types_.STRING, - values: tizen.ApplicationId, optional: false, nullable:false }, { name: 'successCallback', type: types_.FUNCTION, - //values: RemoteAppControlCallback, optional: true, nullable: true }, { name: 'errorCallback', type: types_.FUNCTION, - //values: ErrorCallback, optional: true, nullable: true } @@ -544,7 +536,7 @@ RemoteAppControlService.prototype.launch = function(appId, successCallback, erro var lid = this._serviceId; // TODO In fact it must be a list of callbacks - // But untill D2D FW suppurts transaction management, it is meaningless to + // But until D2D FW supports transaction management, it is meaningless to // have more than one callback, because all payload is delivered to // a single point without identification of initial request this._remoteAppControlCallback = successCallback; @@ -574,8 +566,7 @@ RemoteAppControlService.prototype.launchAppControl = function() { nullable:false }, { name: 'appId', - type: types_.PLATFORM_OBJECT, - values: tizen.ApplicationId, + type: types_.STRING, optional: true, nullable: true }, { diff --git a/src/convergence/convergence_instance.cc b/src/convergence/convergence_instance.cc index 7e8dc0a..cd14512 100644 --- a/src/convergence/convergence_instance.cc +++ b/src/convergence/convergence_instance.cc @@ -191,8 +191,6 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceConnect(const pi CHECK_EXIST(args, kJSArgumentDeviceId); CHECK_EXIST(args, kJSCurrentListenerId); - LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); - auto connect = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("connect"); @@ -211,7 +209,11 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceConnect(const pi result = service->Connect(static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - this->Post(token, result); + //only in case of failure call callback + //other cases are handled by conv_service_connected_cb() + if (!result) { + this->Post(token, result); + } }; std::thread(connect, token).detach(); @@ -226,8 +228,6 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceDisconnect(const CHECK_PRIVILEGE(kPrivilegeInternet); CHECK_PRIVILEGE(kPrivilegeBluetooth); - //LoggerI("ARGS: %s", args.serialize().c_str()); - auto disconnect = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("disconnect"); @@ -262,8 +262,6 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceStart(const pico CHECK_EXIST(args, kJSArgumentReply); CHECK_EXIST(args, kJSCurrentListenerId); - LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); - auto start = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("start"); @@ -283,7 +281,11 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceStart(const pico static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - this->Post(token, result); + //only in case of failure call callback + //other cases are handled by conv_service_listener_cb() + if (!result) { + this->Post(token, result); + } }; std::thread(start, token).detach(); @@ -301,8 +303,6 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceStop(const picoj CHECK_EXIST(args, kJSArgumentReply); CHECK_EXIST(args, kJSCurrentListenerId); - LoggerI("ARGS: %s", picojson::value(args).serialize().c_str()); - auto stop = [this, args](const common::AsyncToken& token) -> void { ScopeLogger("stop"); @@ -322,7 +322,11 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceStop(const picoj static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - this->Post(token, result); + //only in case of failure call callback + //other cases are handled by conv_service_listener_cb() + if (!result) { + this->Post(token, result); + } }; std::thread(stop, token).detach(); @@ -362,7 +366,11 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunch(const pic static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - this->Post(token, result); + //only in case of failure call callback + //other cases are handled by conv_service_listener_cb() + if (!result) { + this->Post(token, result); + } }; std::thread(launch, token).detach(); @@ -403,7 +411,11 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunchAppControl static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - this->Post(token, result); + //only in case of failure call callback + //other cases are handled by conv_service_listener_cb() + if (!result) { + this->Post(token, result); + } }; std::thread(launch_app_control, token).detach(); diff --git a/src/convergence/convergence_remote_app_control_service.cc b/src/convergence/convergence_remote_app_control_service.cc index c0ec611..201b26d 100644 --- a/src/convergence/convergence_remote_app_control_service.cc +++ b/src/convergence/convergence_remote_app_control_service.cc @@ -54,7 +54,7 @@ ConvergenceRemoteAppControlService::ConvergenceRemoteAppControlService(conv_devi ConvergenceRemoteAppControlService::~ConvergenceRemoteAppControlService() { ScopeLogger(); - // Release all memory, used by callback paramerers + // Release all memory, used by callback parameters for (size_t i = 0; i < callback_param_gc_.size(); i++) { delete callback_param_gc_[i]; } @@ -84,7 +84,7 @@ void ConvergenceRemoteAppControlService::ServiceConnectedCb(conv_service_h servi true, param); } else { - // Error occured during connection + // Error occurred during connection param[kServiceConnectionStatus] = picojson::value(kServiceConnectionStatusNotConnected); callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback, callbackParam->callback_id_, @@ -119,8 +119,9 @@ TizenResult ConvergenceRemoteAppControlService::Disconnect() { ScopeLogger(); conv_service_h service = FindServiceHandle(); - if (!service) + if (!service) { return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); + } const int error = conv_service_disconnect(service); if (CONV_ERROR_NONE != error) { @@ -215,7 +216,7 @@ void ConvergenceRemoteAppControlService::ServiceListenerCb(conv_service_h servic true, param); } else { - // Error occured during connection + // Error occurred during connection param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusError); param[kServiceListenerError] = picojson::value(static_cast(error)); callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback, -- 2.7.4 From c415d195de2036d35e354fcf94cb0a53eb1eef3c Mon Sep 17 00:00:00 2001 From: "taekeun.kang" Date: Wed, 30 Nov 2016 16:47:02 +0900 Subject: [PATCH 10/16] [Common] fix bug in tools.cc - missing '}' Change-Id: I493872f648b6adab262deb826034cad19a277f07 Signed-off-by: taekeun.kang --- src/common/tools.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/tools.cc b/src/common/tools.cc index d961c50..21f5064 100644 --- a/src/common/tools.cc +++ b/src/common/tools.cc @@ -150,6 +150,7 @@ class AccessControlImpl { LoggerD("Enter"); return true; + } }; #elif PRIVILEGE_USE_CYNARA -- 2.7.4 From e028ded95c6dbf43fca09ed8c52177c6770b7a43 Mon Sep 17 00:00:00 2001 From: "jk.pu" Date: Wed, 30 Nov 2016 17:37:39 +0900 Subject: [PATCH 11/16] [version] 1.53 Change-Id: I5000310f64d0911926fd8659157ed6914e81d3de Signed-off-by: jk.pu --- packaging/webapi-plugins.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec index 361b04c..ae2935a 100644 --- a/packaging/webapi-plugins.spec +++ b/packaging/webapi-plugins.spec @@ -10,7 +10,7 @@ %define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions} Name: webapi-plugins -Version: 1.52 +Version: 1.53 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries -- 2.7.4 From e44ca5565b8f6c4b26be05ab5c55413c96ed57f7 Mon Sep 17 00:00:00 2001 From: Lukasz Bardeli Date: Wed, 30 Nov 2016 15:41:29 +0100 Subject: [PATCH 12/16] [Convergance] change call successCallbackin AppCommunicationClientService.disconnect() [Verification] Code compiles without error Change-Id: I8dd051670f0477bdd88fbb2f40ff66b579801e6c Signed-off-by: Lukasz Bardeli --- src/convergence/convergence_api.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index 81718f5..9e362c5 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -1001,14 +1001,12 @@ AppCommunicationClientService.prototype.connect = function(successCallback, erro { name: 'successCallback', type: types_.FUNCTION, - //values: ConnectSuccessCallback, optional: false, nullable: false }, { name: 'errorCallback', type: types_.FUNCTION, - //values: ErrorCallback, optional: true, nullable: true } @@ -1061,6 +1059,8 @@ AppCommunicationClientService.prototype.disconnect = function(successCallback, e }, function(result) { if (native_.isFailure(result)) { native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(successCallback, this); } }); @@ -1069,8 +1069,6 @@ AppCommunicationClientService.prototype.disconnect = function(successCallback, e } else { updateWithInternalData({ connectionState: ConnectionState.NOT_CONNECTED }, this); } - - native_.callIfPossible(successCallback, this); }; function ChannelInfo(uri_, id_) { -- 2.7.4 From 1e63ac5796ac957c07b6445577b053dca2fb1617 Mon Sep 17 00:00:00 2001 From: Piotr Kosko Date: Thu, 1 Dec 2016 12:19:11 +0100 Subject: [PATCH 13/16] [Convergence] Reporting error while disconnect fails Change-Id: I0c75536ffa79d89f1fd999646256195a5b33000c Signed-off-by: Piotr Kosko --- src/convergence/convergence_api.js | 14 +++++++------- .../convergence_app_communication_service.cc | 19 ++++++++++++++++--- .../convergence_remote_app_control_service.cc | 18 ++++++++++++++++-- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index 9e362c5..615b81c 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -421,21 +421,21 @@ RemoteAppControlService.prototype.disconnect = function(successCallback, errorCa throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is not connected yet.'); } + var that = this; var result = native_.call('RemoteAppControlService_disconnect', { deviceId: this._deviceId }, function(result) { if (native_.isFailure(result)) { native_.callIfPossible(errorCallback, native_.getErrorObject(result)); + } else { + updateWithInternalData({ connectionState: ConnectionState.NOT_CONNECTED }, that); + native_.callIfPossible(successCallback, that); } }); if (native_.isFailure(result)) { throw native_.getErrorObject(result); - } else { - updateWithInternalData({ connectionState: ConnectionState.NOT_CONNECTED }, this); } - - native_.callIfPossible(successCallback, this); }; RemoteAppControlService.prototype.start = function() { @@ -1054,20 +1054,20 @@ AppCommunicationClientService.prototype.disconnect = function(successCallback, e if (this.connectionState != ConnectionState.CONNECTED) throw new WebAPIException(WebAPIException.INVALID_STATE_ERR, 'Service is not connected yet.'); + var that = this; var result = native_.call('AppCommunicationClientService_disconnect', { deviceId: this._deviceId }, function(result) { if (native_.isFailure(result)) { native_.callIfPossible(errorCallback, native_.getErrorObject(result)); } else { - native_.callIfPossible(successCallback, this); + updateWithInternalData({ connectionState: ConnectionState.NOT_CONNECTED }, that); + native_.callIfPossible(successCallback, that); } }); if (native_.isFailure(result)) { throw native_.getErrorObject(result); - } else { - updateWithInternalData({ connectionState: ConnectionState.NOT_CONNECTED }, this); } }; diff --git a/src/convergence/convergence_app_communication_service.cc b/src/convergence/convergence_app_communication_service.cc index 42ce200..4272e4e 100644 --- a/src/convergence/convergence_app_communication_service.cc +++ b/src/convergence/convergence_app_communication_service.cc @@ -467,14 +467,27 @@ common::TizenResult ConvergenceAppCommunicationClientService::Disconnect() { if (!service) return LogAndCreateTizenError(AbortError, "Service is NULL"); - const int error = conv_service_disconnect(service); + int error = conv_service_disconnect(service); if (CONV_ERROR_NONE != error) { - // TODO: Handle error trace_conv_error(error, __LINE__, "conv_service_disconnect"); return LogAndCreateTizenError(AbortError, "conv_service_disconnect [fail]"); } - return TizenSuccess(); + conv_service_connection_state_e state = CONV_SERVICE_CONNECTION_STATE_NONE; + error = conv_service_get_connection_state(service, &state); + if (CONV_ERROR_NONE != error) { + LoggerE("Error gathering state [%d] : %s", error, get_error_message(error)); + return LogAndCreateTizenError(AbortError, "Error gathering state"); + } else { + LoggerD("state: %d" , state); + + } + if (CONV_SERVICE_CONNECTION_STATE_NOT_CONNECTED == state) { + return TizenSuccess(); + } else { + LoggerE("Service is still connected, reporting error"); + return LogAndCreateTizenError(AbortError, "Disconnecting failed."); + } } diff --git a/src/convergence/convergence_remote_app_control_service.cc b/src/convergence/convergence_remote_app_control_service.cc index 201b26d..bd9612b 100644 --- a/src/convergence/convergence_remote_app_control_service.cc +++ b/src/convergence/convergence_remote_app_control_service.cc @@ -123,7 +123,7 @@ TizenResult ConvergenceRemoteAppControlService::Disconnect() { return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } - const int error = conv_service_disconnect(service); + int error = conv_service_disconnect(service); if (CONV_ERROR_NONE != error) { return LogAndCreateTizenError(AbortError, "conv_service_disconnect [Fail]"); } else { @@ -132,7 +132,21 @@ TizenResult ConvergenceRemoteAppControlService::Disconnect() { LoggerI("Disconnected from the remote service"); } - return TizenSuccess(); + conv_service_connection_state_e state = CONV_SERVICE_CONNECTION_STATE_NONE; + error = conv_service_get_connection_state(service, &state); + if (CONV_ERROR_NONE != error) { + LoggerE("Error gathering state [%d] : %s", error, get_error_message(error)); + return LogAndCreateTizenError(AbortError, "Error gathering state"); + } else { + LoggerD("state: %d" , state); + + } + if (CONV_SERVICE_CONNECTION_STATE_NOT_CONNECTED == state) { + return TizenSuccess(); + } else { + LoggerE("Service is still connected, reporting error"); + return LogAndCreateTizenError(AbortError, "Disconnecting failed."); + } } TizenResult ConvergenceRemoteAppControlService::Start(const bool reply, const int cur_listener_id) { -- 2.7.4 From a721e535e74883a56e8ce39498ed4798d2036942 Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Fri, 2 Dec 2016 16:31:24 +0900 Subject: [PATCH 14/16] [Convergence] Fix for launch() and launchAppControl() [Verification] Code compiles. Application on remote device can be launched, resulut is received and passed to JS layer. Application does not crash now. Change-Id: I45345a302a0601895bda5593700c80be3c877b95 Signed-off-by: Tomasz Marciniak --- src/convergence/convergence_api.js | 29 +++++-- src/convergence/convergence_instance.cc | 8 +- .../convergence_remote_app_control_service.cc | 89 ++++++++++++++++------ .../convergence_remote_app_control_service.h | 4 +- src/convergence/convergence_utils.h | 7 +- 5 files changed, 95 insertions(+), 42 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index 615b81c..708fbc0 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -302,8 +302,18 @@ native_.addListener('REMOTE_APP_CONTROL_SERVICE_LISTENER', function(result) { native_.callIfPossible(s._connectCallback, s); break; case 'onPublish': - native_.callIfPossible(s._remoteAppControlCallback, - result.payload); + var remote_func = result.remote_function; + if ('launch' === remote_func) { + native_.callIfPossible(s._remoteAppControlCallback); + } else if ('launchAppControl' === remote_func) { + var callback = result.callback_result; + var d = undefined; + if ('onsuccess' === callback) { + d = result.reply ? new tizen.ApplicationControlData('reply', [result.reply]) : null; + } + + native_.callIfPossible(s._remoteAppControlCallback[callback], d); + } break; case 'onStart': native_.callIfPossible(s._startCallback, s); @@ -542,11 +552,8 @@ RemoteAppControlService.prototype.launch = function(appId, successCallback, erro this._remoteAppControlCallback = successCallback; convergenceServices[lid] = this; - var needReply = !(successCallback == null); - var result = native_.call('RemoteAppControlService_launch', { appId: args.appId, - reply: needReply, deviceId: this._deviceId, curListenerId: lid }, function(result) { @@ -579,22 +586,30 @@ RemoteAppControlService.prototype.launchAppControl = function() { type: types_.FUNCTION, optional: true, nullable: true + }, { + name: 'replyCallback', + type : types_.LISTENER, + values : ['onsuccess', 'onfailure'], + optional: true, + nullable: true }]); var lid = this._serviceId; - this._remoteAppControlCallback = args.successCallback; + this._remoteAppControlCallback = args.replyCallback; convergenceServices[lid] = this; var callArgs = {}; callArgs.appControl = args.appControl; callArgs.appId = args.appId ? args.appId : ""; - callArgs.reply = !!args.successCallback; + callArgs.reply = !!args.replyCallback; callArgs.deviceId = this._deviceId; callArgs.curListenerId = lid; var callback = function(result) { if (native_.isFailure(result)) { native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); + } else { + native_.callIfPossible(args.successCallback); } }; diff --git a/src/convergence/convergence_instance.cc b/src/convergence/convergence_instance.cc index cd14512..622d850 100644 --- a/src/convergence/convergence_instance.cc +++ b/src/convergence/convergence_instance.cc @@ -343,7 +343,6 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunch(const pic 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 { @@ -362,7 +361,6 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunch(const pic } 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())); } @@ -411,11 +409,7 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunchAppControl static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); } - //only in case of failure call callback - //other cases are handled by conv_service_listener_cb() - if (!result) { - this->Post(token, result); - } + this->Post(token, result); }; std::thread(launch_app_control, token).detach(); diff --git a/src/convergence/convergence_remote_app_control_service.cc b/src/convergence/convergence_remote_app_control_service.cc index bd9612b..f652523 100644 --- a/src/convergence/convergence_remote_app_control_service.cc +++ b/src/convergence/convergence_remote_app_control_service.cc @@ -32,6 +32,11 @@ namespace convergence { namespace { static const char* kAppControl = "app_control"; static const char* kReply = "reply"; +static const char* kCbResult = "callback_result"; +static const char* kRemoteFunc = "remote_function"; + +static const std::string kLaunch = "launch"; +static const std::string kLaunchAppControl = "launchAppControl"; } // namespace using common::TizenResult; @@ -215,20 +220,41 @@ void ConvergenceRemoteAppControlService::ServiceListenerCb(conv_service_h servic } picojson::object param; - param["payload"] = picojson::value("TODO"); - - // TODO parse the payload and fill the param - const std::string result_type = ConvergencePayloadArray::ExtractPayloadString(result, kServiceResultType.c_str()); param[kServiceResultType] = picojson::value(result_type); - if (CONV_ERROR_NONE == error) { - param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusOk); - callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback, - callbackParam->callback_id_, - true, - param); + //onPublish are triggered by launch() and launchAppControl() methods + if (kServiceResultTypeOnPublish == result_type) { + param[kRemoteFunc] = picojson::value(callbackParam->remote_method_); + //there is no information which method caused callback execution + //so it is needed to provide such information via callbackParam + if (kLaunchAppControl == callbackParam->remote_method_) { + const std::string app_control_result = ConvergencePayloadArray::ExtractPayloadString(result, kServiceReplyControlResult.c_str()); + if ("0" == app_control_result) { + const std::string app_control_reply = ConvergencePayloadArray::ExtractPayloadString(result, kServiceReplyResult.c_str()); + + param[kCbResult] = picojson::value("onsuccess"); + param[kReply] = picojson::value(app_control_reply); + } else { + param[kCbResult] = picojson::value("onfailure"); + } + } + + //in case of launch() method there is no information received if it finished + //with success or error, so we assume optimistic success + param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusOk); + callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback, + callbackParam->callback_id_, + true, + param); + } else { + param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusOk); + callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback, + callbackParam->callback_id_, + true, + param); + } } else { // Error occurred during connection param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusError); @@ -240,7 +266,7 @@ void ConvergenceRemoteAppControlService::ServiceListenerCb(conv_service_h servic } } -void ConvergenceRemoteAppControlService::UpdateListener(const int cur_listener_id) { +void ConvergenceRemoteAppControlService::UpdateListener(const int cur_listener_id, std::string remote_method) { ScopeLogger(); conv_service_h service_handle = FindServiceHandle(); @@ -250,6 +276,7 @@ void ConvergenceRemoteAppControlService::UpdateListener(const int cur_listener_i } CallbackParam *param = new CallbackParam(convergence_plugin_, cur_listener_id); + param->remote_method_ = remote_method; const int error = conv_service_set_listener_cb(service_handle, ServiceListenerCb, param); if (CONV_ERROR_NONE != error) { @@ -263,7 +290,7 @@ void ConvergenceRemoteAppControlService::UpdateListener(const int cur_listener_i } } -TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool reply, const int cur_listener_id) { +TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, const int cur_listener_id) { ScopeLogger(); if (!started_) { @@ -273,12 +300,21 @@ TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool r conv_payload_h payload = nullptr; app_control_h app_control = nullptr; + //regarding to native team app_control can be released + //after setting it in payload handle, unfortunately + //when it is done here or in triggered callback or even + //if they are kept in vector and released in + //~ConvergenceRemoteAppControlService() application crashes. + //it seems that ownership is taken over somewhere and + //handle is released. We need to wait for convergence + //native team answer. Now app_control_destroy is commented SCOPE_EXIT { if (payload) { conv_payload_destroy(payload); } if (app_control) { - app_control_destroy(app_control); + //uncomment below line when issue will be explained + //app_control_destroy(app_control); } }; @@ -292,6 +328,7 @@ TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool r return LogAndCreateTizenError(AbortError, "Failed to create payload handle"); } + ret = app_control_create(&app_control); if (APP_CONTROL_ERROR_NONE != ret) { return LogAndCreateTizenError(AbortError, "Failed to create app control handle"); @@ -312,17 +349,12 @@ TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool r return LogAndCreateTizenError(AbortError, "Failed to set app control in payload"); } - if (reply) { - ret = conv_payload_set_string(payload, kReply, "1"); - if (CONV_ERROR_NONE != ret) { - return LogAndCreateTizenError(AbortError, "Failed to set string in payload"); - } - } + //if the 'reply' was set callback was not triggered because + //D2D-CONV-MANAGER received error IOTCON_ERROR_INVALID_PARAMETER -22 + //RemoteAppControlServiceProvider.cpp: __on_response(741) > iotcon_response_get_result() Fail(-22) // Update listener: assign it if it is not yet assigned - if (reply) { - UpdateListener(cur_listener_id); - } + UpdateListener(cur_listener_id, "launch"); // Sending app control on the remote device ret = conv_service_publish(service_handle, nullptr, payload); @@ -348,12 +380,21 @@ TizenResult ConvergenceRemoteAppControlService::LaunchAppControl(const picojson: conv_payload_h payload = nullptr; app_control_h app_control = nullptr; + //regarding to native team app_control can be released + //after setting it in payload handle, unfortunately + //when it is done here or in triggered callback or even + //if they are kept in vector and released in + //~ConvergenceRemoteAppControlService() application crashes. + //it seems that ownership is taken over somewhere and + //handle is released. We need to wait for convergence + //native team answer. Now app_control_destroy is commented SCOPE_EXIT { if (payload) { conv_payload_destroy(payload); } if (app_control) { - app_control_destroy(app_control); + //uncomment below line when issue will be explained + //app_control_destroy(app_control); } }; @@ -457,7 +498,7 @@ TizenResult ConvergenceRemoteAppControlService::LaunchAppControl(const picojson: // Update listener: assign it if it is not yet assigned if (reply) { - UpdateListener(cur_listener_id); + UpdateListener(cur_listener_id, "launchAppControl"); } // Sending app control on the remote device diff --git a/src/convergence/convergence_remote_app_control_service.h b/src/convergence/convergence_remote_app_control_service.h index a43294f..bf1de55 100644 --- a/src/convergence/convergence_remote_app_control_service.h +++ b/src/convergence/convergence_remote_app_control_service.h @@ -45,7 +45,7 @@ class ConvergenceRemoteAppControlService : public ConvergenceService { 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 Launch(const char *appId, const int cur_listener_id); common::TizenResult LaunchAppControl(const picojson::object& jsonAppControl, const char *appId, bool reply, @@ -54,7 +54,7 @@ class ConvergenceRemoteAppControlService : public ConvergenceService { common::TizenResult ApplicationControlDataToServiceExtraData( const picojson::object& app_control_data, app_control_h app_control); - void UpdateListener(const int cur_listener_id); + void UpdateListener(const int cur_listener_id, std::string remote_method = ""); 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.h b/src/convergence/convergence_utils.h index ab4570e..50e0490 100644 --- a/src/convergence/convergence_utils.h +++ b/src/convergence/convergence_utils.h @@ -38,6 +38,8 @@ class ConvergenceInstance; namespace { // Service result type static const std::string kServiceResultType = "result_type"; +static const std::string kServiceReplyResult = "app_control_reply"; +static const std::string kServiceReplyControlResult = "app_control_result"; static const std::string kServiceResultTypeOnStart = "onStart"; static const std::string kServiceResultTypeOnStop = "onStop"; static const std::string kServiceResultTypeOnConnect = "onConnect"; @@ -61,10 +63,11 @@ static const std::string kServiceListenerError = "error"; } // namespace struct CallbackParam { - CallbackParam(ConvergenceInstance *plg, int cbId) - : plugin_(plg), callback_id_(cbId) {} + CallbackParam(ConvergenceInstance *plg, int cbId) + : plugin_(plg), callback_id_(cbId), remote_method_() {} ConvergenceInstance *plugin_; int callback_id_; + std::string remote_method_; }; -- 2.7.4 From fa7e3ee6dbda59eaec352eeed8fb82dc2e721400 Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Fri, 2 Dec 2016 19:20:04 +0900 Subject: [PATCH 15/16] [Convergence] Return InvalidValuesError if id is empty. [Verification] Code compiles. Proper error is returned in error callback. Change-Id: I55c6c7fbb786022bdbe882bd9ee99cae0654242b Signed-off-by: Tomasz Marciniak --- src/convergence/convergence_instance.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/convergence/convergence_instance.cc b/src/convergence/convergence_instance.cc index 622d850..4ad3807 100644 --- a/src/convergence/convergence_instance.cc +++ b/src/convergence/convergence_instance.cc @@ -359,9 +359,12 @@ common::TizenResult ConvergenceInstance::RemoteAppControlServiceLaunch(const pic result = LogAndCreateTizenError(AbortError, "Can not find the service type = 1", ("Can not find the service type = 1")); } else { - result = service->Launch( - ConvergenceUtils::GetArg(args, kJSArgumentAppId).to_str().c_str(), - static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); + std::string id = ConvergenceUtils::GetArg(args, kJSArgumentAppId).to_str(); + if (id.empty()) { + result = LogAndCreateTizenError(InvalidValuesError, "Invalid app id", ("Invalid app id")); + } else { + result = service->Launch(id.c_str(), static_cast(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get())); + } } //only in case of failure call callback -- 2.7.4 From 78dc7d8010d0e9377de12c9f085beeeabe5339ae Mon Sep 17 00:00:00 2001 From: Piotr Kosko Date: Fri, 2 Dec 2016 14:40:35 +0100 Subject: [PATCH 16/16] [Convergence] Fixed clientInfo in callback of start method [Feature] Fixed filling clientInfo when calling start callback of client service (both for service found on other device with startDiscovery and for local service created with constructor) Change-Id: If2d0e1808df46a8e41415a98e680c86ed0bedf59 Signed-off-by: Piotr Kosko --- src/convergence/convergence_api.js | 3 +- .../convergence_app_communication_service.cc | 59 ++++++++++++++-------- .../convergence_app_communication_service.h | 2 +- src/convergence/convergence_client_info.cc | 2 +- src/convergence/convergence_utils.h | 16 +++++- 5 files changed, 55 insertions(+), 27 deletions(-) diff --git a/src/convergence/convergence_api.js b/src/convergence/convergence_api.js index 708fbc0..3d4650d 100644 --- a/src/convergence/convergence_api.js +++ b/src/convergence/convergence_api.js @@ -714,8 +714,9 @@ native_.addListener('APP_COMMUNICATION_SERVICE_LISTENER', function(result) { native_.callIfPossible(s._connectCallback, s); break; case 'onStart': + var clientInfo = (result.clientInfo ? new ClientInfo(result.clientInfo) : null); native_.callIfPossible(s._startCallback, - new ChannelInfo(result.channel.uri, result.channel.id), null); + new ChannelInfo(result.channel.uri, result.channel.id), clientInfo); break; case 'onPublish': native_.callIfPossible(s._sendCallback, diff --git a/src/convergence/convergence_app_communication_service.cc b/src/convergence/convergence_app_communication_service.cc index 4272e4e..2b71890 100644 --- a/src/convergence/convergence_app_communication_service.cc +++ b/src/convergence/convergence_app_communication_service.cc @@ -37,6 +37,7 @@ using common::TizenSuccess; namespace { static const std::string kChannel = "channel"; +static const std::string kClientInfo = "clientInfo"; } // namespace ConvergenceAppCommunicationService::ConvergenceAppCommunicationService() @@ -72,7 +73,7 @@ common::TizenResult ConvergenceAppCommunicationService::Start( return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); } - UpdateListener(cur_listener_id); + UpdateListener(cur_listener_id, REMOTE_SERVICE_START); const int error = conv_service_start(service_handle, channel->GetHandle(), nullptr); if (CONV_ERROR_NONE != error) { @@ -185,8 +186,11 @@ void ConvergenceAppCommunicationService::ServiceListenerCb(conv_service_h servic param[kChannel] = ConvergenceChannel::ToJson(channel_handle); param[kServiceResultType] = picojson::value(result_type); - if ((kServiceResultTypeOnStart == result_type) - || (kServiceResultTypeOnPublish == result_type) + if (kServiceResultTypeOnStart == result_type) { + if (callbackParam->client_info_) { + param[kClientInfo] = callbackParam->client_info_->ToJson(); + } + } else if ((kServiceResultTypeOnPublish == result_type) || (kServiceResultTypeOnStop == result_type)) { // The service doesn't send any callback with thie response } else if (kServiceResultTypeOnMessage == result_type) { @@ -194,10 +198,20 @@ void ConvergenceAppCommunicationService::ServiceListenerCb(conv_service_h servic ConvergencePayloadArray::ExtractPayloadString(result, "from")); // Define the string as a constant param[kPayload] = ConvergencePayloadArray::ToJson(result); } else if (kServiceResultTypeOnConnect == result_type) { - //param["clientInfo"] = ConvergenceClientInfo(result).ToJson(); - //callbackParam->plugin_->ReplyAsync(kAppCommunicationClientServiceConnectCallback, - // callbackParam->callback_id_, true, param); - return; + // just filling client_info_ member in CallbackParam + if (!callbackParam->client_info_) { + callbackParam->client_info_ = new ConvergenceClientInfo(result); + } + if (LOCAL_SERVICE_START != callbackParam->type_) { + // for non-local services just set clientInfo and not trigger callback + return; + } else { + // but trigger this callback for local services and pretend that this is onStart signal + param[kServiceResultType] = picojson::value(kServiceResultTypeOnStart); + if (callbackParam->client_info_) { + param[kClientInfo] = callbackParam->client_info_->ToJson(); + } + } } else if (kServiceResultTypeOnClientConnect == result_type) { // TODO the service doesn't send any callback with thie response return; // TODO @@ -217,7 +231,8 @@ void ConvergenceAppCommunicationService::ServiceListenerCb(conv_service_h servic callbackParam->callback_id_, true, param); } -void ConvergenceAppCommunicationService::UpdateListener(const int cur_listener_id) { +void ConvergenceAppCommunicationService::UpdateListener(const int cur_listener_id, + ServiceRequestType type) { ScopeLogger(); // TODO make sure that callback is not called twice for the same listener @@ -255,7 +270,7 @@ void ConvergenceAppCommunicationService::UpdateListener(const int cur_listener_i free(sver); } - CallbackParam *param = new CallbackParam(convergence_plugin_, cur_listener_id); + CallbackParam *param = new CallbackParam(convergence_plugin_, cur_listener_id, type); const int error = conv_service_set_listener_cb(service_handle, ServiceListenerCb, param); if (CONV_ERROR_NONE != error) { @@ -348,24 +363,24 @@ common::TizenResult ConvergenceAppCommunicationServerService::Start( const int cur_listener_id) { ScopeLogger(); + LoggerI("Starting service [0x%x] with handle [0x%x]", this, service_handle_); + std::unique_ptr ch_ptr(channel); // auto release memory in case of error - /* By implementation, the local App Communication Service doesn't send - * the callback confirming that the Start is successful. - * So we are sending this callback manually - */ - picojson::object param; - param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusOk); + conv_service_h service_handle = FindServiceHandle(); + if (!service_handle) { + return LogAndCreateTizenError(AbortError, "Service with specified type does not exist"); + } - param[kChannel] = ConvergenceChannel::ToJson(channel->GetHandle()); // Define string as constant - param[kServiceResultType] = picojson::value(kServiceResultTypeOnStart); + UpdateListener(cur_listener_id, LOCAL_SERVICE_START); - common::TizenResult result = ConvergenceAppCommunicationService::Start(channel, cur_listener_id); - if (!result) { - return result; + const int error = conv_service_start(service_handle, channel->GetHandle(), nullptr); + if (CONV_ERROR_NONE != error) { + return LogAndCreateTizenError(AbortError, "conv_service_start [fail]"); } - convergence_plugin_->ReplyAsync(kAppCommunicationListenerCallback, cur_listener_id, true, param); - return result; + opened_channels.push_back(ch_ptr.release()); + + return TizenSuccess(); } common::TizenResult ConvergenceAppCommunicationServerService::Stop( diff --git a/src/convergence/convergence_app_communication_service.h b/src/convergence/convergence_app_communication_service.h index 3821886..10ec5d9 100644 --- a/src/convergence/convergence_app_communication_service.h +++ b/src/convergence/convergence_app_communication_service.h @@ -55,12 +55,12 @@ class ConvergenceAppCommunicationService : public ConvergenceService { common::TizenResult SetListener(const int cur_listener_id); common::TizenResult RemoveListener(); private: - void UpdateListener(const int cur_listener_id); static void ServiceListenerCb(conv_service_h service_handle, conv_channel_h channel_handle, conv_error_e error, conv_payload_h result, void* user_data); protected: + void UpdateListener(const int cur_listener_id, ServiceRequestType type = UNKNOWN_REQUEST_TYPE); std::vector callback_param_gc_; }; diff --git a/src/convergence/convergence_client_info.cc b/src/convergence/convergence_client_info.cc index 6dece11..b75c2e7 100644 --- a/src/convergence/convergence_client_info.cc +++ b/src/convergence/convergence_client_info.cc @@ -76,7 +76,7 @@ picojson::value ConvergenceClientInfo::ToJson() const { ScopeLogger(); picojson::object clientInfo; clientInfo["isHost"] = picojson::value(static_cast(isHost_)); - clientInfo["connectionTime"] = picojson::value(static_cast(connectionTime_)); + clientInfo["connectTime"] = picojson::value(static_cast(connectionTime_)); clientInfo["clientId"] = picojson::value(clientId_); return picojson::value(clientInfo); } diff --git a/src/convergence/convergence_utils.h b/src/convergence/convergence_utils.h index 50e0490..2d17d8a 100644 --- a/src/convergence/convergence_utils.h +++ b/src/convergence/convergence_utils.h @@ -24,6 +24,7 @@ #include #include "common/tizen_result.h" +#include "convergence_client_info.h" namespace extension { namespace convergence { @@ -62,12 +63,23 @@ static const std::string kServiceListenerStatusError = "listener_error"; static const std::string kServiceListenerError = "error"; } // namespace +enum ServiceRequestType { + LOCAL_SERVICE_START, + REMOTE_SERVICE_START, + UNKNOWN_REQUEST_TYPE +}; + struct CallbackParam { - CallbackParam(ConvergenceInstance *plg, int cbId) - : plugin_(plg), callback_id_(cbId), remote_method_() {} + CallbackParam(ConvergenceInstance *plg, int cbId, ServiceRequestType type = UNKNOWN_REQUEST_TYPE) + : plugin_(plg), callback_id_(cbId), remote_method_(), client_info_(nullptr), type_(type) {} + ~CallbackParam() { + delete client_info_; + } ConvergenceInstance *plugin_; int callback_id_; std::string remote_method_; + ConvergenceClientInfo* client_info_; + ServiceRequestType type_; }; -- 2.7.4