From 5bd316c50eb740aad0ee8a230f6ed7b18fb21eb0 Mon Sep 17 00:00:00 2001 From: Szymon Jastrzebski Date: Thu, 17 Aug 2017 09:00:14 +0200 Subject: [PATCH 01/16] [Sensor] Fix for HRM Sensor Change Listener An exception was thrown when trying to call 'tryCall' with data received from C++ layer, making it not possible to set listener for HRM Sensor. sensorType string starts with 'LED_' but there are no any sensor in _sensorListeners object. [Verification] Sensor TCT passed 100% (TW1). Change-Id: I1b4ffe6ac754c6c407ebafea94b1eda48b59844d Signed-off-by: Szymon Jastrzebski --- src/sensor/sensor_api.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sensor/sensor_api.js b/src/sensor/sensor_api.js index 88426a0..5070009 100755 --- a/src/sensor/sensor_api.js +++ b/src/sensor/sensor_api.js @@ -161,6 +161,9 @@ var _sensorListeners = { }; var _listener = function(object) { + if (object.sensorType.startsWith('LED_')) { + object.sensorType = 'HRM_RAW'; + } _sensorListeners[object.sensorType].tryCall(object); }; -- 2.7.4 From 60f5c501f628cbb217c3845653cbd1189811d38d Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Wed, 16 Aug 2017 14:39:52 +0200 Subject: [PATCH 02/16] [Filesystem] Fix for moving files on different file systems [Verification] Code compiles. Now files can be moved between different mounted file systems. TCT pass rate 100% (286/286/0/0/0) Change-Id: I5b70bc96f14a53bcebd2b2db3f12748949aab410 Signed-off-by: Tomasz Marciniak --- src/filesystem/filesystem_manager.cc | 52 +++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/filesystem/filesystem_manager.cc b/src/filesystem/filesystem_manager.cc index 43f7462..15dd88c 100644 --- a/src/filesystem/filesystem_manager.cc +++ b/src/filesystem/filesystem_manager.cc @@ -316,19 +316,53 @@ void FilesystemManager::Rename( const std::function& error_cb) { LoggerD("enter"); + int status = rename(oldPath.c_str(), newPath.c_str()); - if (0 == status) { - FilesystemStat fileStat = FilesystemStat::getStat(newPath); - if (fileStat.valid) { - success_cb(FilesystemStat::getStat(newPath)); - } else { - LoggerE("Cannot perform stat on new path!"); + if (0 != status) { + if(EXDEV != errno) { + LoggerE("Error while moving file"); error_cb(FilesystemError::Other); + return; + } + + LoggerD("Files are not on the same mounted file system"); + //In case of EXDEV we need to copy and remove file + //EXDEV - oldpath and newpath are not on the same mounted file system. + //Linux permits a file system to be mounted at multiple points, but rename() does not work + //across different mount points, even if the same file system is mounted on both. + + if (FilesystemError::None != copyFile(oldPath, newPath)) { + LoggerE("Error while copying file"); + error_cb(FilesystemError::Other); + return; + } + + struct stat fileStat; + if (0 != stat(oldPath.c_str(), &fileStat)) { + LoggerE("Error while getting file status [%s]", GetErrorString(errno).c_str()); + error_cb(FilesystemError::Other); + return; + } + + int ret = 0; + ret |= chmod(newPath.c_str(), fileStat.st_mode); + ret |= chown(newPath.c_str(), fileStat.st_uid, fileStat.st_gid); + if (0 != ret) { + LoggerE("Error while changing ownership/permissions [%s]", GetErrorString(errno).c_str()); + remove(newPath.c_str()); + error_cb(FilesystemError::Other); + return; + } + + if (0 != remove(oldPath.c_str())) { + LoggerE("Error while removing file [%s]", GetErrorString(errno).c_str()); + remove(newPath.c_str()); + error_cb(FilesystemError::Other); + return; } - } else { - LoggerE("Cannot rename file: %s", GetErrorString(errno).c_str()); - error_cb(FilesystemError::Other); } + + success_cb(FilesystemStat::getStat(newPath)); } void FilesystemManager::ReadDir( -- 2.7.4 From c62f7857490af586a3c5d79b287d797f3849d219 Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Thu, 17 Aug 2017 14:17:20 +0200 Subject: [PATCH 03/16] [version 1.97] Change-Id: I84d1035105246be61f76dc052f626c52fc83faa3 Signed-off-by: Tomasz Marciniak --- 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 2d60819..41ac187 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.96 +Version: 1.97 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries -- 2.7.4 From fbffbbfa405dd67990a58c232335ef603fb2a1e1 Mon Sep 17 00:00:00 2001 From: Szymon Jastrzebski Date: Mon, 21 Aug 2017 11:35:52 +0200 Subject: [PATCH 04/16] [Sensor] Fixing DefaultEventComparator Comparator DefaultEventComparator should iterate through all received values. It should NOT compare timestamps. The amount of received values depend on the type of used sensor. The sensor_value_count_ values are taken from Native Sensor's Guides. [Verification] Code compiles. TCT (TW1) passed 100%. Change-Id: I60d5af338a7feea2dd4fb40cdff0f6bd03f8d650 Signed-off-by: Szymon Jastrzebski --- src/sensor/sensor_service.cc | 60 ++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/src/sensor/sensor_service.cc b/src/sensor/sensor_service.cc index 88f68b2..71a3ab2 100755 --- a/src/sensor/sensor_service.cc +++ b/src/sensor/sensor_service.cc @@ -175,21 +175,27 @@ PlatformResult GetSensorPlatformResult(const int error_code, const std::string & } } -bool MagneticEventComparator(sensor_event_s* l, sensor_event_s* r) { - return (l->values[0] == r->values[0] && - l->values[1] == r->values[1] && - l->values[2] == r->values[2] && - l->accuracy == r->accuracy); +bool DefaultEventComparator(sensor_event_s* l, sensor_event_s* r, const unsigned int value_count) { + for (unsigned int i = 0; i < value_count; ++i) { + if (l->values[i] != r->values[i]) { + return false; + } + } + return true; +} + +bool MagneticEventComparator(sensor_event_s* l, sensor_event_s* r, const unsigned int value_count) { + return DefaultEventComparator(l, r, value_count) ? l->accuracy == r->accuracy : false; } } // namespace class SensorData { public: - typedef bool (*EventComparator)(sensor_event_s* l, sensor_event_s* r); + typedef bool (*EventComparator)(sensor_event_s* l, sensor_event_s* r, const unsigned int value_count); SensorData(SensorInstance& instance, sensor_type_e type_enum, - const std::string& name, EventComparator comparator = + const std::string& name, const unsigned int sensor_value_count, EventComparator comparator = DefaultEventComparator); virtual ~SensorData(); @@ -213,10 +219,10 @@ class SensorData { private: static void SensorCallback(sensor_h sensor, sensor_event_s* event, void* user_data); - static bool DefaultEventComparator(sensor_event_s* l, sensor_event_s* r); sensor_type_e type_enum_; EventComparator comparator_; + const unsigned int sensor_value_count_; sensor_h handle_; sensor_listener_h listener_; sensor_event_s previous_event_; @@ -226,9 +232,11 @@ class SensorData { }; SensorData::SensorData(SensorInstance& instance, sensor_type_e type_enum, - const std::string& name, EventComparator comparator) + const std::string& name, const unsigned int sensor_value_count, + EventComparator comparator) : type_enum_(type_enum), comparator_(comparator), + sensor_value_count_(sensor_value_count), handle_(nullptr), listener_(nullptr), previous_event_(), @@ -270,10 +278,6 @@ void SensorData::SensorCallback(sensor_h sensor, sensor_event_s* event, void* us Instance::PostMessage(&that->instance_, result.serialize().c_str()); } -bool SensorData::DefaultEventComparator(sensor_event_s* l, sensor_event_s* r) { - return (l->timestamp == r->timestamp); -} - PlatformResult SensorData::CheckInitialization() { LoggerD("Entered: %s", type_to_string_map[type()].c_str()); @@ -348,7 +352,7 @@ bool SensorData::is_supported() { bool SensorData::UpdateEvent(sensor_event_s* event) { LoggerD("Entered: %s", type_to_string_map[type()].c_str()); - if (comparator_(&previous_event_, event)) { + if (comparator_(&previous_event_, event, sensor_value_count_)) { // previous and current events are the same -> no update return false; } else { @@ -662,11 +666,12 @@ class HrmSensorData : public SensorData { }; HrmSensorData::HrmSensorData(SensorInstance& instance) - : SensorData(instance, SENSOR_CUSTOM, "HRM_RAW") { + : SensorData(instance, SENSOR_CUSTOM, "HRM_RAW", 1) { LoggerD("Entered: %s", type_to_string_map[type()].c_str()); - AddSensor(new SensorData(instance, SENSOR_HRM_LED_IR, "LED_IR")); - AddSensor(new SensorData(instance, SENSOR_HRM_LED_RED, "LED_RED")); - AddSensor(new SensorData(instance, SENSOR_HRM_LED_GREEN, "LED_GREEN")); + // For amount of retrieved values from sensors please refer to native guides. + AddSensor(new SensorData(instance, SENSOR_HRM_LED_IR, "LED_IR", 1)); + AddSensor(new SensorData(instance, SENSOR_HRM_LED_RED, "LED_RED", 1)); + AddSensor(new SensorData(instance, SENSOR_HRM_LED_GREEN, "LED_GREEN", 1)); } HrmSensorData::~HrmSensorData() { @@ -812,16 +817,17 @@ SensorService::SensorService(SensorInstance& instance) : instance_(instance) { LoggerD("Entered"); - AddSensor(new SensorData(instance, SENSOR_LIGHT, "LIGHT")); - AddSensor(new SensorData(instance, SENSOR_MAGNETIC, "MAGNETIC", MagneticEventComparator)); - AddSensor(new SensorData(instance, SENSOR_PRESSURE, "PRESSURE")); - AddSensor(new SensorData(instance, SENSOR_PROXIMITY, "PROXIMITY")); - AddSensor(new SensorData(instance, SENSOR_ULTRAVIOLET, "ULTRAVIOLET")); + // For amount of retrieved values from sensors please refer to native guides. + AddSensor(new SensorData(instance, SENSOR_LIGHT, "LIGHT", 1)); + AddSensor(new SensorData(instance, SENSOR_MAGNETIC, "MAGNETIC", 3, MagneticEventComparator)); + AddSensor(new SensorData(instance, SENSOR_PRESSURE, "PRESSURE", 1)); + AddSensor(new SensorData(instance, SENSOR_PROXIMITY, "PROXIMITY", 1)); + AddSensor(new SensorData(instance, SENSOR_ULTRAVIOLET, "ULTRAVIOLET", 1)); AddSensor(new HrmSensorData(instance)); - AddSensor(new SensorData(instance, SENSOR_GRAVITY, "GRAVITY")); - AddSensor(new SensorData(instance, SENSOR_GYROSCOPE, "GYROSCOPE")); - AddSensor(new SensorData(instance, SENSOR_GYROSCOPE_ROTATION_VECTOR, "GYROSCOPE_ROTATION_VECTOR")); - AddSensor(new SensorData(instance, SENSOR_LINEAR_ACCELERATION, "LINEAR_ACCELERATION")); + AddSensor(new SensorData(instance, SENSOR_GRAVITY, "GRAVITY", 3)); + AddSensor(new SensorData(instance, SENSOR_GYROSCOPE, "GYROSCOPE", 3)); + AddSensor(new SensorData(instance, SENSOR_GYROSCOPE_ROTATION_VECTOR, "GYROSCOPE_ROTATION_VECTOR", 4)); + AddSensor(new SensorData(instance, SENSOR_LINEAR_ACCELERATION, "LINEAR_ACCELERATION", 3)); } SensorService::~SensorService() { -- 2.7.4 From b8c4fb3379446eb639e78fbf00d04644f3cfdac3 Mon Sep 17 00:00:00 2001 From: Piotr Kosko Date: Mon, 21 Aug 2017 12:30:13 +0200 Subject: [PATCH 05/16] [version] 1.98 Change-Id: I751ce338fdcce6ab1de120b31b427cbbad065b34 Signed-off-by: Piotr Kosko --- 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 41ac187..4f453a5 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.97 +Version: 1.98 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries -- 2.7.4 From fd29eb43608a2107fd6a31938adb54c37fd153d5 Mon Sep 17 00:00:00 2001 From: Tomasz Marciniak Date: Mon, 28 Aug 2017 14:27:47 +0200 Subject: [PATCH 06/16] [Sensor] Check if error callback exists before calling [Verification] Code compiles. Exception is not throw if error callback is not defined. TCT pass rate did not change. Change-Id: I95053c70e598c1a17022edebdd6be8a334a05a06 Signed-off-by: Tomasz Marciniak --- src/sensor/sensor_api.js | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/sensor/sensor_api.js b/src/sensor/sensor_api.js index 5070009..df4aeb9 100755 --- a/src/sensor/sensor_api.js +++ b/src/sensor/sensor_api.js @@ -160,6 +160,14 @@ var _sensorListeners = { 'LINEAR_ACCELERATION' : {} }; +var errorWrapper = function (err) { + if(err.name === "UnknownError") { + err = new WebAPIException(WebAPIException.ABORT_ERR, err.message); + } + + native_.callIfPossible(this.errorCallback, err); +}; + var _listener = function(object) { if (object.sensorType.startsWith('LED_')) { object.sensorType = 'HRM_RAW'; @@ -509,14 +517,7 @@ GravitySensor.prototype.getGravitySensorData = function() { } ]); - function errorWrapper(err) { - if (err.name === "UnknownError") { - args.errorCallback(new WebAPIException(WebAPIException.ABORT_ERR, err.message)); - } else { - args.errorCallback(err); - } - } - _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper); + _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args)); }; @@ -543,14 +544,7 @@ GyroscopeSensor.prototype.getGyroscopeSensorData = function() { } ]); - function errorWrapper(err) { - if (err.name === "UnknownError") { - args.errorCallback(new WebAPIException(WebAPIException.ABORT_ERR, err.message)); - } else { - args.errorCallback(err); - } - } - _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper); + _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args)); }; //// GyroscopeRotationVectorSensor @@ -576,14 +570,7 @@ GyroscopeRotationVectorSensor.prototype.getGyroscopeRotationVectorSensorData = f } ]); - function errorWrapper(err) { - if (err.name === "UnknownError") { - args.errorCallback(new WebAPIException(WebAPIException.ABORT_ERR, err.message)); - } else { - args.errorCallback(err); - } - } - _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper); + _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args)); }; //// LinearAccelerationSensor @@ -609,14 +596,7 @@ LinearAccelerationSensor.prototype.getLinearAccelerationSensorData = function() } ]); - function errorWrapper(err) { - if (err.name === "UnknownError") { - args.errorCallback(new WebAPIException(WebAPIException.ABORT_ERR, err.message)); - } else { - args.errorCallback(err); - } - } - _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper); + _sensorListeners[this.sensorType].getData(args.successCallback, errorWrapper.bind(args)); }; -- 2.7.4 From b549a862944c3b6000689415276dcc12015a0f0d Mon Sep 17 00:00:00 2001 From: Piotr Kosko Date: Wed, 30 Aug 2017 12:30:29 +0200 Subject: [PATCH 07/16] [version] 1.99 Change-Id: I7ddff1b2974fe3361f62d498f736ec9ab779681d Signed-off-by: Piotr Kosko --- 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 4f453a5..5a2092a 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.98 +Version: 1.99 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries -- 2.7.4 From 2eb229555ffb8528d14ff74116b677cbea3f2fda Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Tue, 29 Aug 2017 16:12:17 +0200 Subject: [PATCH 08/16] [Download] Enable download with net_proxy [Verification] TCT download pass rate, (wearable connected to the internet with Android mobile as a network proxy, no Wi-Fi/cellular network connection): 100 % Change-Id: I0efb8c2d5281d5249dad46d58eaf8aa7c5ddc930 Signed-off-by: Pawel Wasowski --- src/download/download_instance.cc | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/download/download_instance.cc b/src/download/download_instance.cc index 490c183..dca989a 100755 --- a/src/download/download_instance.cc +++ b/src/download/download_instance.cc @@ -514,43 +514,41 @@ void DownloadInstance::DownloadManagerStart bool network_support = false; bool cell_support = false; bool wifi_support = false; - bool ethernet_support = false; system_info_get_platform_bool("http://tizen.org/feature/network.telephony", &cell_support); system_info_get_platform_bool("http://tizen.org/feature/network.wifi", &wifi_support); - system_info_get_platform_bool("http://tizen.org/feature/network.ethernet", - ðernet_support); connection_h connection = nullptr; connection_create(&connection); connection_cellular_state_e cell_state = CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE; connection_wifi_state_e wifi_state = CONNECTION_WIFI_STATE_DEACTIVATED; - connection_ethernet_state_e ethernet_state = CONNECTION_ETHERNET_STATE_DEACTIVATED; connection_get_cellular_state(connection, &cell_state); connection_get_wifi_state(connection, &wifi_state); - connection_get_ethernet_state(connection, ðernet_state); + + connection_type_e connection_type = CONNECTION_TYPE_DISCONNECTED; + connection_get_type(connection, &connection_type); + connection_destroy(connection); bool network_available = false; bool cell_available = (CONNECTION_CELLULAR_STATE_CONNECTED == cell_state); bool wifi_available = (CONNECTION_WIFI_STATE_CONNECTED == wifi_state); - bool ethernet_available = CONNECTION_ETHERNET_STATE_CONNECTED == ethernet_state; - if (networkType == "CELLULAR") { + if ("CELLULAR" == networkType) { network_support = cell_support; network_available = cell_available; diPtr->network_type = DOWNLOAD_NETWORK_DATA_NETWORK; - } else if (networkType == "WIFI") { + } else if ("WIFI" == networkType) { network_support = wifi_support; network_available = wifi_available; diPtr->network_type = DOWNLOAD_NETWORK_WIFI; - } else if (networkType == "ALL") { - network_support = cell_support || wifi_support || ethernet_support; - network_available = cell_available || wifi_available || ethernet_available; + } else if (("ALL" == networkType) && (CONNECTION_TYPE_DISCONNECTED != connection_type)) { + network_support = true; + network_available = true; diPtr->network_type = DOWNLOAD_NETWORK_ALL; } else { LogAndReportError( @@ -561,7 +559,10 @@ void DownloadInstance::DownloadManagerStart return; } - if (!network_support) { + /* + * There is no relevant feature for networkType == "ALL". + */ + if (!network_support && ("ALL" != networkType)) { LogAndReportError( common::PlatformResult(common::ErrorCode::NOT_SUPPORTED_ERR, "The networkType of the given DownloadRequest " -- 2.7.4 From f7de488267f08a3f840e93e93be526a6b49d8317 Mon Sep 17 00:00:00 2001 From: Szymon Jastrzebski Date: Thu, 31 Aug 2017 13:54:52 +0200 Subject: [PATCH 09/16] [MediaController] Fixing client's listeners Listeners, which are registered per MediaControllerServerInfo object work globally. This causes to invoke the registered listener for every change in any server. [Verification] TCT MC 100% pass rate. Change-Id: I950e047b07a16d351959fe98e47ea1ca7ff68518 Saaigned-off-by: Szymon Jastrzebski --- src/mediacontroller/mediacontroller_api.js | 54 ++++++++++++++++++++++++--- src/mediacontroller/mediacontroller_client.cc | 6 +++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/mediacontroller/mediacontroller_api.js b/src/mediacontroller/mediacontroller_api.js index c5a8197..4852464 100755 --- a/src/mediacontroller/mediacontroller_api.js +++ b/src/mediacontroller/mediacontroller_api.js @@ -34,6 +34,8 @@ var internal_commands_ = { function ListenerManager(native, listenerName, handle) { this.listeners = {}; + this.listenerNameToIds = {}; + this.listenerIdToName = {}; this.nextId = 1; this.nativeSet = false; this.native = native; @@ -63,12 +65,55 @@ ListenerManager.prototype.addListener = function(callback) { return id; }; +ListenerManager.prototype.addServerInfoListener = function(callback, name) { + var id = this.nextId; + if (!this.nativeSet) { + this.native.addListener(this.listenerName, function(msg) { + if (this.listenerNameToIds.hasOwnProperty(msg.name)) { + var cbArray = this.listenerNameToIds[msg.name]; + for (var i = 0; i < cbArray.length; ++i) { + var watchId = cbArray[i]; + this.handle(msg, this.listeners[watchId], watchId); + } + } + }.bind(this)); + + this.nativeSet = true; + } + + this.listenerIdToName[id] = name; + if (this.listenerNameToIds[name]) { + this.listenerNameToIds[name].push(id); + } else { + this.listenerNameToIds[name] = [id]; + } + this.listeners[id] = callback; + ++this.nextId; + return id; +}; + ListenerManager.prototype.removeListener = function(watchId) { if (this.listeners.hasOwnProperty(watchId)) { delete this.listeners[watchId]; } }; +function removeArrayElement(arr, elem) { + var index = arr.indexOf(elem); + if (index !== -1) { + arr.splice(index, 1); + } +} + +ListenerManager.prototype.removeServerInfoListener = function(watchId) { + this.removeListener(watchId); + if (this.listenerIdToName.hasOwnProperty(watchId)) { + var name = this.listenerIdToName[watchId]; + removeArrayElement(this.listenerNameToIds[name], watchId); + delete this.listenerIdToName[watchId]; + } +}; + var ServerCommandListener = new ListenerManager(native_, '_ServerCommandListener', function(msg, listener) { var data = undefined; data = listener(msg.clientName, msg.command, msg.data); @@ -718,8 +763,7 @@ MediaControllerServerInfo.prototype.addServerStatusChangeListener = function(lis throw native_.getErrorObject(result); } } - - return ServerInfoStatusListener.addListener(args.listener); + return ServerInfoStatusListener.addServerInfoListener(args.listener, this.name); }; MediaControllerServerInfo.prototype.removeServerStatusChangeListener = function(watchId) { @@ -727,7 +771,7 @@ MediaControllerServerInfo.prototype.removeServerStatusChangeListener = function( {name: 'watchId', type: types_.LONG} ]); - ServerInfoStatusListener.removeListener(args.watchId); + ServerInfoStatusListener.removeServerInfoListener(args.watchId); if (type_.isEmptyObject(ServerInfoStatusListener.listeners)) { native_.callSync('MediaControllerServerInfo_removeServerStatusChangeListener'); @@ -756,7 +800,7 @@ MediaControllerServerInfo.prototype.addPlaybackInfoChangeListener = function(lis } } - return ServerInfoPlaybackInfoListener.addListener(args.listener); + return ServerInfoPlaybackInfoListener.addServerInfoListener(args.listener, this.name); }; MediaControllerServerInfo.prototype.removePlaybackInfoChangeListener = function(watchId) { @@ -764,7 +808,7 @@ MediaControllerServerInfo.prototype.removePlaybackInfoChangeListener = function( {name: 'watchId', type: types_.LONG} ]); - ServerInfoPlaybackInfoListener.removeListener(args.watchId); + ServerInfoPlaybackInfoListener.removeServerInfoListener(args.watchId); if (type_.isEmptyObject(ServerInfoPlaybackInfoListener.listeners)) { native_.callSync('MediaControllerServerInfo_removePlaybackInfoChangeListener'); diff --git a/src/mediacontroller/mediacontroller_client.cc b/src/mediacontroller/mediacontroller_client.cc index f48d8a1..8cb9cdd 100644 --- a/src/mediacontroller/mediacontroller_client.cc +++ b/src/mediacontroller/mediacontroller_client.cc @@ -314,6 +314,7 @@ void MediaControllerClient::OnServerStatusUpdate(const char* server_name, picojson::object& data_o = data.get(); data_o["state"] = picojson::value(state_str); + data_o["name"] = picojson::value(server_name); client->server_status_listener_(&data); } @@ -429,6 +430,7 @@ void MediaControllerClient::OnPlaybackUpdate(const char *server_name, data_o["action"] = picojson::value(std::string("onplaybackchanged")); data_o["state"] = picojson::value(state); data_o["position"] = picojson::value(position); + data_o["name"] = picojson::value(server_name); client->playback_info_listener_(&data); } @@ -450,6 +452,7 @@ void MediaControllerClient::OnShuffleModeUpdate(const char *server_name, data_o["action"] = picojson::value(std::string("onshufflemodechanged")); data_o["mode"] = picojson::value(mode == MC_SHUFFLE_MODE_ON); + data_o["name"] = picojson::value(server_name); client->playback_info_listener_(&data); } @@ -471,6 +474,7 @@ void MediaControllerClient::OnRepeatModeUpdate(const char *server_name, data_o["action"] = picojson::value(std::string("onrepeatmodechanged")); data_o["mode"] = picojson::value(mode == MC_REPEAT_MODE_ON); + data_o["name"] = picojson::value(server_name); client->playback_info_listener_(&data); } @@ -500,6 +504,7 @@ void MediaControllerClient::OnMetadataUpdate(const char* server_name, data_o["action"] = picojson::value(std::string("onmetadatachanged")); data_o["metadata"] = metadata; + data_o["name"] = picojson::value(server_name); client->playback_info_listener_(&data); } @@ -590,6 +595,7 @@ void MediaControllerClient::OnCommandReply(const char* server_name, return; } reply_o["data"] = data; + reply_o["name"] = picojson::value(server_name); client->command_reply_callback_(&reply); } -- 2.7.4 From 23c3d470bc23804fdafe7772499a1e09e398d668 Mon Sep 17 00:00:00 2001 From: Michal Bistyga Date: Tue, 29 Aug 2017 17:20:39 +0200 Subject: [PATCH 10/16] [Application] Adding debug logs Change-Id: I9fca94f5bda30b39bfff700f8cd37c5abe81d9f3 Signed-off-by: Michal Bistyga --- src/application/application_manager.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/application/application_manager.cc b/src/application/application_manager.cc index 0d8ed50..b900c78 100755 --- a/src/application/application_manager.cc +++ b/src/application/application_manager.cc @@ -599,8 +599,10 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) { int ret = 0; while (retry < retry_count) { - ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data); + LoggerD("Calling launch request. Attempt number: %d", retry); + ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data); + LoggerD("App control launch request returned: %d, %s", ret, get_error_message(ret)); if (APP_CONTROL_ERROR_NONE == ret) { break; } @@ -609,8 +611,6 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) { struct timespec sleep_time = { 0, 300L * 1000L * 1000L }; nanosleep(&sleep_time, nullptr); ++retry; - - LoggerD("Retry launch request: %d", retry); } if (APP_CONTROL_ERROR_NONE != ret) { @@ -640,11 +640,12 @@ void ApplicationManager::LaunchAppControl(const picojson::value& args) { return; } } - ReportSuccess(response->get()); }; auto launch_response = [this](const std::shared_ptr& response) -> void { + LoggerD("Entered launch_response"); + Instance::PostMessage(&this->instance_, response->serialize().c_str()); }; -- 2.7.4 From c6e38b0eca5109c63dcb3639e8f469c2226fa554 Mon Sep 17 00:00:00 2001 From: Szymon Jastrzebski Date: Tue, 5 Sep 2017 12:31:17 +0200 Subject: [PATCH 11/16] [NBS] Fix for releasing domains. Change-Id: I47a2a86d93e11b6b2f7d02001ec6eda4f65e0b30 Signed-off-by: Tomasz Marciniak Signed-off-by: Szymon Jastrzebski --- .../networkbearerselection_api.js | 24 +- .../networkbearerselection_instance.cc | 183 +++--- .../networkbearerselection_instance.h | 19 +- .../networkbearerselection_manager.cc | 715 ++++++++++----------- .../networkbearerselection_manager.h | 90 +-- 5 files changed, 484 insertions(+), 547 deletions(-) diff --git a/src/networkbearerselection/networkbearerselection_api.js b/src/networkbearerselection/networkbearerselection_api.js index fde026b..f0c3bc1 100644 --- a/src/networkbearerselection/networkbearerselection_api.js +++ b/src/networkbearerselection/networkbearerselection_api.js @@ -21,7 +21,6 @@ var validator_ = utils_.validator; var types_ = validator_.Types; var native_ = new xwalk.utils.NativeManager(extension); - var NetworkType = { CELLULAR: 'CELLULAR', UNKNOWN: 'UNKNOWN' @@ -40,15 +39,15 @@ function _networkBearerSelectionCallback(result) { for (id in callbacks) { if (callbacks.hasOwnProperty(result.id) && result.id == id) { callback = callbacks[id]; - if (result.state === 'Success') { + if (result.status === 'success') { native_.callIfPossible(callback.onsuccess); } - if (result.state === 'Disconnected') { + + if (result.status === 'disconnected') { native_.callIfPossible(callback.ondisconnected); - native_.removeListener('NetworkBearerSelectionCallback_' + id); - delete callbacks[id]; } - if (result.state === 'Error') { + + if (result.status === 'error') { native_.callIfPossible(callback.onerror, native_.getErrorObject(result)); native_.removeListener('NetworkBearerSelectionCallback_' + id); delete callbacks[id]; @@ -60,7 +59,7 @@ function _networkBearerSelectionCallback(result) { function NetworkBearerSelection() {} -NetworkBearerSelection.prototype.requestRouteToHost = function(networkType, domainName, successCallback, errorCallback) { +NetworkBearerSelection.prototype.requestRouteToHost = function() { var args = validator_.validateArgs(arguments, [ {name: 'networkType', type: types_.ENUM, values: Object.keys(NetworkType)}, {name: 'domainName', type: types_.STRING}, @@ -90,7 +89,7 @@ NetworkBearerSelection.prototype.requestRouteToHost = function(networkType, doma } }; -NetworkBearerSelection.prototype.releaseRouteToHost = function(networkType, domainName, successCallback, errorCallback) { +NetworkBearerSelection.prototype.releaseRouteToHost = function() { var args = validator_.validateArgs(arguments, [ {name: 'networkType', type: types_.ENUM, values: Object.keys(NetworkType)}, {name: 'domainName', type: types_.STRING}, @@ -98,21 +97,24 @@ NetworkBearerSelection.prototype.releaseRouteToHost = function(networkType, doma {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} ]); + var nativeParam = { + domainName: args.domainName + }; + var callback = function(result) { if (native_.isFailure(result)) { native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); return; } - native_.callIfPossible(args.successCallback); + args.successCallback(); }; - var result = native_.call('NetworkBearerSelection_releaseRouteToHost', args, callback); + var result = native_.call('NetworkBearerSelection_releaseRouteToHost', nativeParam, callback); if (native_.isFailure(result)) { throw native_.getErrorObject(result); } }; - exports = new NetworkBearerSelection(); diff --git a/src/networkbearerselection/networkbearerselection_instance.cc b/src/networkbearerselection/networkbearerselection_instance.cc index babbebf..e8f0bd6 100644 --- a/src/networkbearerselection/networkbearerselection_instance.cc +++ b/src/networkbearerselection/networkbearerselection_instance.cc @@ -18,6 +18,7 @@ #include +#include "networkbearerselection_manager.h" #include "common/picojson.h" #include "common/logger.h" #include "common/platform_exception.h" @@ -28,18 +29,19 @@ namespace extension { namespace networkbearerselection { namespace { -// The privileges that required in NetworkBearerSelection API -const std::string kPrivilegeNetworkBearerSelection = "http://tizen.org/privilege/networkbearerselection"; + +const std::string kPrivilegeNBS = "http://tizen.org/privilege/networkbearerselection"; const std::string kPrivilegeInternet = "http://tizen.org/privilege/internet"; -const std::vector kNbsPrivileges{kPrivilegeNetworkBearerSelection, kPrivilegeInternet}; +const std::vector kNbsPrivileges{kPrivilegeNBS, kPrivilegeInternet}; -} // namespace +const std::string kNBSCallback = "NetworkBearerSelectionCallback_"; +} // namespace using namespace common; using namespace extension::networkbearerselection; NetworkBearerSelectionInstance::NetworkBearerSelectionInstance() { - LoggerD("Enter"); + LoggerD("Entered"); using std::placeholders::_1; using std::placeholders::_2; @@ -60,7 +62,7 @@ NetworkBearerSelectionInstance::NetworkBearerSelectionInstance() { } NetworkBearerSelectionInstance::~NetworkBearerSelectionInstance() { - LoggerD("Enter"); + LoggerD("Entered"); NetworkBearerSelectionManager::GetInstance()->RemoveListener(this); } @@ -71,9 +73,8 @@ NetworkBearerSelectionInstance::~NetworkBearerSelectionInstance() { } void NetworkBearerSelectionInstance::NetworkBearerSelectionRequestRouteToHost( - const picojson::value& args, - picojson::object& out) { - LoggerD("enter"); + const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); CHECK_PRIVILEGE_ACCESS(kNbsPrivileges, &out); @@ -81,122 +82,116 @@ void NetworkBearerSelectionInstance::NetworkBearerSelectionRequestRouteToHost( CHECK_EXIST(args, "id", out) const auto status = NetworkBearerSelectionManager::GetInstance()->getCellularState(); - if (!status) { LogAndReportError(status, &out, ("Failed to request route to host")); return; } - const std::string& domainName = args.get("domainName").get(); - const int listenerId = static_cast(args.get("id").get()); + const std::string& domain_name = args.get("domainName").get(); + const int id = static_cast(args.get("id").get()); - auto get = [=]()->void { - NetworkBearerSelectionManager::GetInstance()->requestRouteToHost( - domainName); - }; + auto request = [=]()->void { + auto response = [this, domain_name, id](const common::PlatformResult result) -> void { + LoggerD("Entered"); + + picojson::value value {picojson::object{}}; + picojson::object& obj = value.get(); + + obj["id"] = picojson::value(static_cast(id)); + obj["listenerId"] = picojson::value(kNBSCallback + std::to_string(id)); - listenerMap.insert(std::make_pair(domainName, listenerId)); + if (result.IsSuccess()) { + ReportSuccess(obj); + this->addDomainListener(domain_name, id); + } else { + LogAndReportError(result, &obj); + } - common::TaskQueue::GetInstance().Async(get); + Instance::PostMessage(this, value.serialize().c_str()); + }; + + NetworkBearerSelectionManager::GetInstance()->requestRouteToHost(domain_name, response); + + }; + common::TaskQueue::GetInstance().Async(request); ReportSuccess(out); } void NetworkBearerSelectionInstance::NetworkBearerSelectionReleaseRouteToHost( - const picojson::value& args, - picojson::object& out) { - LoggerD("enter"); + const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); CHECK_PRIVILEGE_ACCESS(kNbsPrivileges, &out); CHECK_EXIST(args, "callbackId", out) CHECK_EXIST(args, "domainName", out) - const double callback_id = args.get("callbackId").get(); - const std::string& domainName = args.get("domainName").get(); - - auto get = [ this, callback_id ](bool status)->void { - LoggerD("enter"); - picojson::value response = picojson::value(picojson::object()); - picojson::object& obj = response.get(); - if (status) { - ReportSuccess(obj); - } else { - LogAndReportError(UnknownException("PLATFORM ERROR"), obj, ("Failed to release route to host (callback)")); - } - obj["callbackId"] = picojson::value(callback_id); - Instance::PostMessage(this, response.serialize().c_str()); - }; - auto reply = [=](bool status)->void { - LoggerD("enter"); - common::TaskQueue::GetInstance().Async(std::bind(get, status)); - }; + const double id = args.get("callbackId").get(); + const std::string& domain_name = args.get("domainName").get(); - const auto status = NetworkBearerSelectionManager::GetInstance() - ->releaseRouteToHost(domainName, reply); - if (status) { - ReportSuccess(out); - } else { - LogAndReportError(status, &out, ("Failed to release route to host")); + { + std::lock_guard lock(m_listener_mutex_); + if (listenerMap.end() == listenerMap.find(domain_name)) { + LogAndReportError(UnknownException("Invalid argument"), out); + return; + } } + + auto release = [=]()->void { + auto response = [this, domain_name, id](const common::PlatformResult result) -> void { + LoggerD("Entered"); + + picojson::value value {picojson::object{}}; + picojson::object& obj = value.get(); + + obj["callbackId"] = picojson::value(id); + + if (result.IsSuccess()) { + ReportSuccess(obj); + this->removeDomainListener(domain_name); + } else { + LogAndReportError(result, &obj); + } + + Instance::PostMessage(this, value.serialize().c_str()); + }; + + NetworkBearerSelectionManager::GetInstance()->releaseRouteToHost(domain_name, response); + }; + common::TaskQueue::GetInstance().Async(release); + ReportSuccess(out); } -void NetworkBearerSelectionInstance::onNBSSuccess( - const std::string& domain_name) { - LoggerD("enter"); +void NetworkBearerSelectionInstance::onNBSEvent(const std::string& status) { + LoggerD("Entered"); + picojson::value event = picojson::value(picojson::object()); picojson::object& obj = event.get(); - obj["domainName"] = picojson::value(domain_name); - obj["state"] = picojson::value("Success"); - - auto iterRange = listenerMap.equal_range(domain_name); - for (auto iter = iterRange.first; iter != iterRange.second; ++iter) { - auto listenerId = (*iter).second; - obj["listenerId"] = picojson::value("NetworkBearerSelectionCallback_" + - std::to_string(listenerId)); - obj["id"] = picojson::value(static_cast(listenerId)); + + obj["status"] = picojson::value(status); + std::lock_guard lock(m_listener_mutex_); + for (auto iter = listenerMap.begin(); iter != listenerMap.end(); ++iter) { + auto listener_id = (*iter).second; + obj["listenerId"] = picojson::value(kNBSCallback + std::to_string(listener_id)); + obj["id"] = picojson::value(static_cast(listener_id)); + LoggerD("Posting: %s", event.serialize().c_str()); Instance::PostMessage(this, event.serialize().c_str()); } } -void NetworkBearerSelectionInstance::onNBSError(const std::string& domain_name, - const std::string& info) { - LoggerD("enter"); - picojson::value event = picojson::value(picojson::object()); - picojson::object& obj = event.get(); - LogAndReportError(UnknownException(info), obj); - obj["domainName"] = picojson::value(domain_name); - obj["state"] = picojson::value("Error"); - - auto iterRange = listenerMap.equal_range(domain_name); - for (auto iter = iterRange.first; iter != iterRange.second; ++iter) { - auto listenerId = (*iter).second; - obj["listenerId"] = picojson::value("NetworkBearerSelectionCallback_" + - std::to_string(listenerId)); - obj["id"] = picojson::value(static_cast(listenerId)); - LoggerD("Posting: %s", event.serialize().c_str()); - Instance::PostMessage(this, event.serialize().c_str()); - } - listenerMap.erase(domain_name); +void NetworkBearerSelectionInstance::addDomainListener( + const std::string& domain_name, int listener_id) { + LoggerD("Entered"); + + std::lock_guard lock(m_listener_mutex_); + listenerMap.insert(std::make_pair(domain_name, listener_id)); } -void NetworkBearerSelectionInstance::onNBSDisconnect( - const std::string& domain_name) { - LoggerD("enter"); - picojson::value event = picojson::value(picojson::object()); - picojson::object& obj = event.get(); - obj["domainName"] = picojson::value(domain_name); - obj["state"] = picojson::value("Disconnected"); - - auto iterRange = listenerMap.equal_range(domain_name); - for (auto iter = iterRange.first; iter != iterRange.second; ++iter) { - auto listenerId = (*iter).second; - obj["listenerId"] = picojson::value("NetworkBearerSelectionCallback_" + - std::to_string(listenerId)); - obj["id"] = picojson::value(static_cast(listenerId)); - LoggerD("Posting: %s", event.serialize().c_str()); - Instance::PostMessage(this, event.serialize().c_str()); - } +void NetworkBearerSelectionInstance::removeDomainListener(const std::string& domain_name) { + LoggerD("Entered"); + + std::lock_guard lock(m_listener_mutex_); listenerMap.erase(domain_name); } diff --git a/src/networkbearerselection/networkbearerselection_instance.h b/src/networkbearerselection/networkbearerselection_instance.h index d07d49c..7bc1d82 100644 --- a/src/networkbearerselection/networkbearerselection_instance.h +++ b/src/networkbearerselection/networkbearerselection_instance.h @@ -18,30 +18,27 @@ #define NETWORKBEARERSELECTION_NETWORKBEARERSELECTION_INSTANCE_H_ #include "common/extension.h" -#include "networkbearerselection_manager.h" #include +#include namespace extension { namespace networkbearerselection { -class NetworkBearerSelectionInstance : public common::ParsedInstance, - public NetworkBearerSelectionListener { +class NetworkBearerSelectionInstance : public common::ParsedInstance { public: NetworkBearerSelectionInstance(); virtual ~NetworkBearerSelectionInstance(); + void onNBSEvent(const std::string& status); private: - void NetworkBearerSelectionRequestRouteToHost(const picojson::value& args, - picojson::object& out); - void NetworkBearerSelectionReleaseRouteToHost(const picojson::value& args, - picojson::object& out); + void NetworkBearerSelectionRequestRouteToHost(const picojson::value& args, picojson::object& out); + void NetworkBearerSelectionReleaseRouteToHost(const picojson::value& args, picojson::object& out); - virtual void onNBSSuccess(const std::string& domain_name); - virtual void onNBSError(const std::string& domain_name, - const std::string& info); - virtual void onNBSDisconnect(const std::string& domain_name); + void addDomainListener(const std::string& domain_name, int listener_id); + void removeDomainListener(const std::string& domain_name); std::multimap listenerMap; + std::mutex m_listener_mutex_; }; } // namespace networkbearerselection diff --git a/src/networkbearerselection/networkbearerselection_manager.cc b/src/networkbearerselection/networkbearerselection_manager.cc index 4c3ff43..f777326 100644 --- a/src/networkbearerselection/networkbearerselection_manager.cc +++ b/src/networkbearerselection/networkbearerselection_manager.cc @@ -21,44 +21,45 @@ #include #include #include +#include namespace extension { namespace networkbearerselection { +using namespace common; + namespace { -const char* kPlatformError = "Platform error"; +const char* kEventSuccess = "success"; +const char* kEventDisconnected = "disconnected"; } -struct NetworkBearerSelectionRequestEvent { +struct NetworkBearerSelectionEvent { std::string domain_name; - NetworkBearerSelectionRequestEvent(const std::string& dm) : domain_name(dm) {} -}; + ReplyCallback callback; -struct NetworkBearerSelectionReleaseEvent { - std::string domain_name; - NetworkBearerSelectionManager::ReleaseReplyCallback callback; - NetworkBearerSelectionReleaseEvent( - const std::string& dm, - const NetworkBearerSelectionManager::ReleaseReplyCallback& cb) - : domain_name(dm), callback(cb) {} + NetworkBearerSelectionEvent(const std::string& dm, const ReplyCallback& cb): + domain_name(dm), + callback(cb) { + } }; -void NetworkBearerSelectionManager::AddListener( - NetworkBearerSelectionListener* listener) { - LoggerD("Enter"); +void NetworkBearerSelectionManager::AddListener(NetworkBearerSelectionInstance* listener) { + LoggerD("Entered"); + std::lock_guard lock(m_mutex_); m_listeners_.push_back(listener); } -void NetworkBearerSelectionManager::RemoveListener( - NetworkBearerSelectionListener* listener) { - LoggerD("Enter"); +void NetworkBearerSelectionManager::RemoveListener(NetworkBearerSelectionInstance* listener) { + LoggerD("Entered"); + std::lock_guard lock(m_mutex_); m_listeners_.remove(listener); } NetworkBearerSelectionManager* NetworkBearerSelectionManager::GetInstance() { - LoggerD("Enter"); + LoggerD("Entered"); + static NetworkBearerSelectionManager instance; return &instance; } @@ -66,11 +67,11 @@ NetworkBearerSelectionManager* NetworkBearerSelectionManager::GetInstance() { NetworkBearerSelectionManager::NetworkBearerSelectionManager() : m_connection_handle_(nullptr), m_profile_handle_(nullptr), - m_connection_state_(ConnectionState::Unknown), - m_is_connection_open_(false) { - LoggerD("Enter"); - int ret = connection_create(&m_connection_handle_); + m_profile_name_(), + m_is_connection_opened_(false) { + LoggerD("Entered"); + int ret = connection_create(&m_connection_handle_); if (CONNECTION_ERROR_NONE == ret) { LoggerD("Client registration success"); } else { @@ -80,482 +81,458 @@ NetworkBearerSelectionManager::NetworkBearerSelectionManager() } NetworkBearerSelectionManager::~NetworkBearerSelectionManager() { - LoggerD("Enter"); - if (m_connection_handle_ != nullptr) { - LoggerD("Client deregistration success"); - destroyProfileHandle(); - connection_destroy(m_connection_handle_); - } else { - LoggerE("Client deregistration failed"); - } + LoggerD("Entered"); - { - std::lock_guard lock(m_request_mutex_); - LoggerD("Delete %d request object(s)", m_request_events_.size()); - m_request_events_.clear(); + for (auto it = m_domain_names_.begin(); it != m_domain_names_.end(); ++it) { + if (!removeDomainRoute(it)) { + LoggerE("Failed to remove route [%s]", it->first.c_str()); + } } - { - std::lock_guard lock(m_release_mutex_); - LoggerD("Delete %d release object(s)", m_release_events_.size()); - m_release_events_.clear(); + if (nullptr != m_connection_handle_) { + destroyProfileHandler(); + if (CONNECTION_ERROR_NONE != connection_destroy(m_connection_handle_)) { + LoggerE("Failed to destroy connection"); + } } } void NetworkBearerSelectionManager::connection_state_changed_callback( - connection_profile_state_e state, - void* user_data) { - LoggerD("enter"); - if (user_data != nullptr) { - LoggerD("Callback registration Succeeded"); - if (state == CONNECTION_PROFILE_STATE_ASSOCIATION) { - LoggerD("association state"); - return; - } + connection_profile_state_e state, void* user_data) { + LoggerD("Entered [%d]", state); - RequestEventPtr event = NetworkBearerSelectionManager::GetInstance()->getRequestEvent( - static_cast(user_data)); - if (!event) { - LoggerD("Event is not found."); - return; - } - - if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) { - std::string domain_name = event->domain_name; - NetworkBearerSelectionManager::GetInstance()->deregistStateChangeListener(domain_name); - - NetworkBearerSelectionManager::GetInstance()->makeDisconnectCallback(domain_name); - } + if (CONNECTION_PROFILE_STATE_CONNECTED == state) { + NetworkBearerSelectionManager::GetInstance()->makeSuccessCallback(); + } else if (CONNECTION_PROFILE_STATE_DISCONNECTED == state) { + NetworkBearerSelectionManager::GetInstance()->makeDisconnectCallback(); } } -void NetworkBearerSelectionManager::connection_profile_opened_callback( - connection_error_e result, - void* user_data) { - LoggerD("enter"); - if (user_data == nullptr) { - LoggerD("Error: null passed in profile open callback"); +void NetworkBearerSelectionManager::connection_opened_callback( + connection_error_e result, void* user_data) { + LoggerD("Entered"); + + if (nullptr == user_data) { + LoggerD("User data not found"); return; } - RequestEventPtr event = NetworkBearerSelectionManager::GetInstance()->getRequestEvent( - static_cast(user_data)); + NetworkBearerSelectionEvent* event = static_cast(user_data); if (!event) { - LoggerD("Event is not found."); + LoggerE("Event not found"); return; } std::string domain_name = event->domain_name; - - if (result == CONNECTION_ERROR_NONE) { - LoggerD("Connection open Succeeded"); - if (user_data != nullptr) { - NetworkBearerSelectionManager::GetInstance()->registStateChangeListener( - domain_name); + ReplyCallback callback = event->callback; + NetworkBearerSelectionManager* manager = NetworkBearerSelectionManager::GetInstance(); + PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR, "Connection opened"); + + LoggerD("Domain name %s", domain_name.c_str()); + if (CONNECTION_ERROR_NONE == result) { + if (!manager->registerStateChangeListener(domain_name)) { + LoggerE("Failed to open connection"); + ret = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to open connection"); } - } else { - LoggerD("Connection open Failed"); - NetworkBearerSelectionManager::GetInstance()->makeErrorCallback( - domain_name, kPlatformError); } + + manager->callResultCallback(callback, ret); + delete event; } void NetworkBearerSelectionManager::connection_closed_callback( - connection_error_e result, - void* user_data) { - LoggerD("enter"); - if (user_data == nullptr) { - LoggerD("Error: null passed in profile open callback"); + connection_error_e result, void* user_data) { + LoggerD("Entered"); + + if (nullptr == user_data) { + LoggerD("User data not found"); return; } - ReleaseEventPtr event = NetworkBearerSelectionManager::GetInstance()->getReleaseEvent( - static_cast(user_data)); + NetworkBearerSelectionEvent* event = static_cast(user_data); if (!event) { - LoggerD("Event is not found."); + LoggerE("Event not found"); return; } std::string domain_name = event->domain_name; - ReleaseReplyCallback callback = event->callback; - - if (result == CONNECTION_ERROR_NONE) { - LoggerD("Connection close Succeeded"); - if (user_data != nullptr) { - NetworkBearerSelectionManager::GetInstance()->deregistStateChangeListener( - domain_name); - callback(true); + ReplyCallback callback = event->callback; + NetworkBearerSelectionManager* manager = NetworkBearerSelectionManager::GetInstance(); + PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR, "Connection closed"); + + LoggerD("Domain name %s", domain_name.c_str()); + if (CONNECTION_ERROR_NONE == result) { + if (!manager->deregisterStateChangeListener(domain_name)) { + LoggerE("Failed to close connection"); + ret = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to close connection"); } - } else { - callback(false); } + + manager->callResultCallback(callback, ret); + delete event; } -common::PlatformResult NetworkBearerSelectionManager::getCellularState() { +PlatformResult NetworkBearerSelectionManager::getCellularState() { + LoggerD("Entered"); connection_cellular_state_e state; int ret = connection_get_cellular_state(m_connection_handle_, &state); - - if (ret != CONNECTION_ERROR_NONE) { + if (CONNECTION_ERROR_NONE != ret) { LoggerE("Fail to get connection state. %d", ret); - return common::PlatformResult(GetNBSErrorCode(ret), - "Fail to get connection state."); + return PlatformResult(GetNBSErrorCode(ret), "Failed to get connection state"); } - if (state == CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE) { + if (CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE == state) { LoggerE("Network cellular have no service. %d", state); - return common::PlatformResult(common::ErrorCode::NOT_SUPPORTED_ERR, - "Network cellular have no service. emulator doesn't support the API."); + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Network cellular have no service"); } - return common::PlatformResult(common::ErrorCode::NO_ERROR); + + return PlatformResult(ErrorCode::NO_ERROR); } +void NetworkBearerSelectionManager::callResultCallback( + const ReplyCallback& reply, const PlatformResult result) { + LoggerD("Entered"); + + std::thread(reply, result).detach(); +} void NetworkBearerSelectionManager::requestRouteToHost( - const std::string& domain_name) { - LoggerD("NetworkBearerSelectionManager::requestRouteToHost"); - connection_profile_h profileHandle; + const std::string& domain_name, const ReplyCallback& reply) { + LoggerD("Entered"); - if (m_connection_state_ == ConnectionState::Connected) { + connection_profile_h profile_h = nullptr; + char* current_profile_name_c = nullptr; + + SCOPE_EXIT { + if (profile_h) { + connection_profile_destroy(profile_h); + } + free(current_profile_name_c); + }; + + if (m_is_connection_opened_) { LoggerD("connection is already opened."); - for (std::list::iterator it = m_domain_names_.begin(); - it != m_domain_names_.end(); - it++) { - if (*it == domain_name) { - LoggerD("Same domain name is exist in list."); - makeSuccessCallback(domain_name); - return; - } + auto it = m_domain_names_.find(domain_name); + if (m_domain_names_.end() != it) { + callResultCallback(reply, PlatformResult(ErrorCode::NO_ERROR, "Domain already requested")); + return; } } - destroyProfileHandle(); - - int ret = connection_get_default_cellular_service_profile( - m_connection_handle_, - CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET, - &m_profile_handle_); - - if (ret != CONNECTION_ERROR_NONE) { - LoggerE("Fail to get profile handle. %d", ret); - makeErrorCallback(domain_name, kPlatformError); + if (!createProfileHandler()) { + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to get cellular profile")); return; } - char* defaultProfileName_c = nullptr; - std::string defaultProfileName; - - connection_profile_get_name(m_profile_handle_, &defaultProfileName_c); - if (defaultProfileName_c == nullptr) { - LoggerE("default profile is not exist."); - makeErrorCallback(domain_name, kPlatformError); + int ret = connection_get_current_profile(m_connection_handle_, &profile_h); + if (CONNECTION_ERROR_NONE != ret) { + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to get current profile")); return; } - defaultProfileName = defaultProfileName_c; - free(defaultProfileName_c); - defaultProfileName_c = nullptr; - if (connection_get_current_profile(m_connection_handle_, &profileHandle) != - CONNECTION_ERROR_NONE) { - LoggerE("Fail to get current profile handle"); - makeErrorCallback(domain_name, kPlatformError); + std::string current_profile_name; + ret = connection_profile_get_name(profile_h, ¤t_profile_name_c); + if (CONNECTION_ERROR_NONE != ret || nullptr == current_profile_name_c) { + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to get profile name")); return; } - char* currentProfileName_c = nullptr; - std::string currentProfileName; - if (connection_profile_get_name(profileHandle, ¤tProfileName_c) != - CONNECTION_ERROR_NONE) { - LoggerE("Fail to get current profile name"); - if (currentProfileName_c != nullptr) { - free(currentProfileName_c); - currentProfileName_c = nullptr; + current_profile_name = current_profile_name_c; + + LoggerD("defaultProfileName [%s]", m_profile_name_.c_str()); + LoggerD("currentProfileName [%s]", current_profile_name.c_str()); + if (!m_is_connection_opened_ || m_profile_name_ != current_profile_name) { + LoggerD("Open profile"); + + NetworkBearerSelectionEvent* event(new NetworkBearerSelectionEvent(domain_name, reply)); + ret = connection_open_profile(m_connection_handle_, m_profile_handle_, + connection_opened_callback, event); + if (CONNECTION_ERROR_NONE != ret) { + delete event; + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to open profile")); } - makeErrorCallback(domain_name, kPlatformError); + return; } - if (currentProfileName_c == nullptr) { - LoggerE("current profile is not exist."); - makeErrorCallback(domain_name, kPlatformError); - return; + bool result = registerStateChangeListener(domain_name); + if (result) { + callResultCallback(reply, PlatformResult(ErrorCode::NO_ERROR, "Domain request success")); + } else { + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener")); } - currentProfileName = currentProfileName_c; - free(currentProfileName_c); - currentProfileName_c = nullptr; +} + +bool NetworkBearerSelectionManager::removeDomainRoute( + const std::map::iterator& iter) { + LoggerD("Entered"); + + const char* domain_name = iter->first.c_str(); + char* interface_name = nullptr; + char* gateway = nullptr; - if (defaultProfileName != currentProfileName) { - RequestEventPtr event(new NetworkBearerSelectionRequestEvent(domain_name)); + SCOPE_EXIT { + free(interface_name); + free(gateway); + }; + + int ret = connection_profile_get_network_interface_name(m_profile_handle_, &interface_name); + if (CONNECTION_ERROR_NONE != ret) { + LoggerE("Failed to get interface name"); + return false; + } - if (connection_open_profile(m_connection_handle_, - m_profile_handle_, - connection_profile_opened_callback, - event.get()) != CONNECTION_ERROR_NONE) { - LoggerE("Connection open Failed"); - makeErrorCallback(domain_name, kPlatformError); - } else { - m_is_connection_open_ = true; + int ai_family = iter->second; + if (AF_INET == ai_family) { + LoggerD("IPv4 address"); + ret = connection_remove_route(m_connection_handle_, interface_name, domain_name); + } else if (AF_INET6 == ai_family) { + LoggerD("IPv6 address"); + ret = connection_profile_get_gateway_address( + m_profile_handle_, CONNECTION_ADDRESS_FAMILY_IPV6, &gateway); - std::lock_guard lock(m_request_mutex_); - m_request_events_.push_back(event); + if (CONNECTION_ERROR_NONE != ret) { + LoggerE("Failed to get gateway"); + return false; } + + ret = connection_remove_route_ipv6( + m_connection_handle_, interface_name, domain_name, gateway); } else { - registStateChangeListener(domain_name); + LoggerE("Incorrect family address"); + return false; + } + + if (CONNECTION_ERROR_NONE != ret) { + LoggerE("Failed to remove route"); + return false; } + + return true; } -common::PlatformResult NetworkBearerSelectionManager::releaseRouteToHost( - const std::string& domain_name, const ReleaseReplyCallback& reply_cb) { - LoggerD("enter"); - - for (const auto& name : m_domain_names_) { - if (name == domain_name) { - LoggerD("Same domain name is exist in list."); - m_domain_names_.remove(domain_name); - LoggerD("list size : %i", m_domain_names_.size()); - if (m_domain_names_.size() == 0) { - if (!m_profile_handle_) { - return LogAndCreateResult(common::ErrorCode::UNKNOWN_ERR, "Already in use"); - } - - if (connection_profile_unset_state_changed_cb(m_profile_handle_) != - CONNECTION_ERROR_NONE) { - LoggerE("unset callback is failed"); - destroyProfileHandle(); - return common::PlatformResult(common::ErrorCode::NO_ERROR); - } - - if (m_is_connection_open_) { - ReleaseEventPtr event(new NetworkBearerSelectionReleaseEvent(domain_name, reply_cb)); - - if (connection_close_profile(m_connection_handle_, - m_profile_handle_, - connection_closed_callback, - event.get()) != CONNECTION_ERROR_NONE) { - LoggerE("connection close failed"); - reply_cb(false); - } else { - m_is_connection_open_ = false; - deregistStateChangeListener(domain_name); - - std::lock_guard lock(m_release_mutex_); - m_release_events_.push_back(event); - } - } else { - reply_cb(true); - } - } - return common::PlatformResult(common::ErrorCode::NO_ERROR); - } +void NetworkBearerSelectionManager::releaseRouteToHost( + const std::string& domain_name, const ReplyCallback& reply) { + LoggerD("Entered"); + + if (!m_profile_handle_) { + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Profile handle not found")); + return; + } + + auto iter = m_domain_names_.find(domain_name); + if (m_domain_names_.end() == iter) { + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Domain not found")); + return; + } + + if (!removeDomainRoute(iter)) { + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to remove route")); + return; + } + + m_domain_names_.erase(iter); + if (m_domain_names_.size()) { + callResultCallback(reply, PlatformResult(ErrorCode::NO_ERROR, "Domain route released")); + return; } - return LogAndCreateResult(common::ErrorCode::UNKNOWN_ERR, "Invalid argument"); + if (m_is_connection_opened_) { + NetworkBearerSelectionEvent* event(new NetworkBearerSelectionEvent(domain_name, reply)); + int ret = connection_close_profile(m_connection_handle_, m_profile_handle_, + connection_closed_callback, event); + if (CONNECTION_ERROR_NONE != ret) { + delete event; + callResultCallback(reply, + LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Failed to close connection")); + return; + } + } } -void NetworkBearerSelectionManager::registStateChangeListener( - const std::string& domain_name) { - LoggerD("enter"); - char* interfaceName = nullptr; - char* hostAddr = nullptr; +bool NetworkBearerSelectionManager::registerStateChangeListener(const std::string& domain_name) { + LoggerD("Entered"); + + char* interface_name = nullptr; char* gateway = nullptr; - std::unique_ptr host_addr_ptr(nullptr, &std::free); - struct addrinfo* servinfo = nullptr; + struct addrinfo* serv_info = nullptr; SCOPE_EXIT { - if (interfaceName) { - free(interfaceName); - } - if (gateway) { - free(gateway); - } - freeaddrinfo(servinfo); + free(interface_name); + free(gateway); + freeaddrinfo(serv_info); }; - if (connection_profile_get_network_interface_name( - m_profile_handle_, &interfaceName) != CONNECTION_ERROR_NONE) { + m_is_connection_opened_ = true; + + int ret = connection_profile_get_network_interface_name(m_profile_handle_, &interface_name); + if (CONNECTION_ERROR_NONE != ret) { LoggerE("Fail to get interface name!"); - destroyProfileHandle(); - makeErrorCallback(domain_name, kPlatformError); - } else { - LoggerD("Interface name : %s", interfaceName); + return false; } + LoggerD("Interface name: %s", interface_name); LoggerD("Domain name to be resolved: %s", domain_name.c_str()); - int ret_val = getaddrinfo(domain_name.c_str() , nullptr , nullptr , &servinfo); - if (0 != ret_val) { - LoggerE("Error while calling getaddrinfo(): %s", gai_strerror(ret_val)); - destroyProfileHandle(); - makeErrorCallback(domain_name, kPlatformError); - return; + ret = getaddrinfo(domain_name.c_str(), nullptr, nullptr, &serv_info); + if (0 != ret) { + LoggerE("Failed to get address info: %s", gai_strerror(ret)); + return false; + } + + struct in_addr *addr = nullptr; + if (AF_INET == serv_info->ai_family) { + LoggerD("IPv4 address"); + struct sockaddr_in *ipv = (struct sockaddr_in *) serv_info->ai_addr; + addr = &(ipv->sin_addr); + } else if (AF_INET6 == serv_info->ai_family) { + LoggerD("IPv6 address"); + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) serv_info->ai_addr; + addr = (struct in_addr*) &ipv6->sin6_addr; } else { - hostAddr = new char[servinfo->ai_addrlen + 1]; - host_addr_ptr.reset(hostAddr); - - struct in_addr *addr = nullptr; - if (AF_INET == servinfo->ai_family) { - LoggerD("IPv4 address"); - struct sockaddr_in *ipv = (struct sockaddr_in *)servinfo->ai_addr; - addr = &(ipv->sin_addr); - } else { - LoggerD("IPv6 address"); - struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)servinfo->ai_addr; - addr = (struct in_addr *) &(ipv6->sin6_addr); - } + LoggerE("Unknown ai_family address"); + return false; + } - if (nullptr == inet_ntop(servinfo->ai_family, addr, hostAddr, servinfo->ai_addrlen)) { - LoggerE("Error while calling inet_ntop()"); - destroyProfileHandle(); - makeErrorCallback(domain_name, kPlatformError); - return; - } - LoggerD("hostAddr : %s", hostAddr); + std::unique_ptr host_addr_ptr(new char[serv_info->ai_addrlen + 1], &std::free); + + if (nullptr == inet_ntop(serv_info->ai_family, addr, host_addr_ptr.get(), serv_info->ai_addrlen)) { + LoggerE("Failed to convert address"); + return false; } - RequestEventPtr event(new NetworkBearerSelectionRequestEvent(domain_name)); + LoggerD("hostAddr: %s", host_addr_ptr.get()); - if (connection_profile_set_state_changed_cb(m_profile_handle_, - connection_state_changed_callback, - event.get()) != CONNECTION_ERROR_NONE) { + ret = connection_profile_set_state_changed_cb( + m_profile_handle_, connection_state_changed_callback, nullptr); + if (CONNECTION_ERROR_NONE != ret ) { LoggerE("Callback register is failed."); - destroyProfileHandle(); + return false; + } + + if (AF_INET == serv_info->ai_family) { + LoggerD("IPv4 add route"); + ret = connection_add_route(m_connection_handle_, interface_name, host_addr_ptr.get()); } else { - int ret = CONNECTION_ERROR_NONE; - if (AF_INET == servinfo->ai_family) { - LoggerD("IPv4 add route"); - ret = connection_add_route(m_connection_handle_, interfaceName, hostAddr); - } else if (AF_INET6 == servinfo->ai_family) { - LoggerD("IPv6 add route"); - ret = connection_profile_get_gateway_address( - m_profile_handle_, CONNECTION_ADDRESS_FAMILY_IPV6, &gateway); - - if (CONNECTION_ERROR_NONE != ret) { - LoggerD("Error %d", ret); - makeErrorCallback(domain_name, kPlatformError); - return; - } - - ret = connection_add_route_ipv6(m_connection_handle_, interfaceName, hostAddr, gateway); - } else { - LoggerE("Unknown ai_family address"); - makeErrorCallback(domain_name, kPlatformError); - return; - } + LoggerD("IPv6 add route"); + ret = connection_profile_get_gateway_address(m_profile_handle_, CONNECTION_ADDRESS_FAMILY_IPV6, &gateway); if (CONNECTION_ERROR_NONE != ret) { - LoggerE("add route is failed."); - connection_profile_unset_state_changed_cb(m_profile_handle_); - makeErrorCallback(domain_name, kPlatformError); - } else { - LoggerD("add route is successed."); - m_domain_names_.push_back(domain_name); - makeSuccessCallback(domain_name); + LoggerE("Error while getting gateway address %d", ret); + return false; } - std::lock_guard lock(m_request_mutex_); - m_request_events_.push_back(event); + ret = connection_add_route_ipv6(m_connection_handle_, interface_name, host_addr_ptr.get(), gateway); + } + + if (CONNECTION_ERROR_NONE != ret) { + LoggerE("Adding route failed"); + return false; + } else { + LoggerD("Adding route success"); + std::lock_guard lock(m_mutex_); + m_domain_names_[domain_name] = serv_info->ai_family; + return true; } } -void NetworkBearerSelectionManager::deregistStateChangeListener( - const std::string& domain_name) { - LoggerD("enter"); +bool NetworkBearerSelectionManager::deregisterStateChangeListener(const std::string& domain_name) { + LoggerD("Entered"); + if (m_profile_handle_) { - connection_profile_unset_state_changed_cb(m_profile_handle_); - connection_profile_destroy(m_profile_handle_); - m_profile_handle_ = nullptr; + int ret = connection_profile_unset_state_changed_cb(m_profile_handle_); + if (CONNECTION_ERROR_NONE != ret) { + LoggerE("Failed to unset state callback"); + return false; + } } - m_domain_names_.remove(domain_name); - m_connection_state_ = ConnectionState::Disconnected; -} -void NetworkBearerSelectionManager::makeSuccessCallback( - const std::string& domain_name) { - LoggerD("enter"); - std::lock_guard lock(m_mutex_); - for (NetworkBearerSelectionListener* listener : m_listeners_) - listener->onNBSSuccess(domain_name); + m_is_connection_opened_ = false; + return true; } -void NetworkBearerSelectionManager::makeErrorCallback( - const std::string& domain_name, - const char* info) { - LoggerD("enter"); - std::string l_info = info; - makeErrorCallback(domain_name, l_info); -} +void NetworkBearerSelectionManager::makeSuccessCallback() { + LoggerD("Entered"); -void NetworkBearerSelectionManager::makeErrorCallback( - const std::string& domain_name, - const std::string& info) { - LoggerD("enter"); std::lock_guard lock(m_mutex_); - for (NetworkBearerSelectionListener* listener : m_listeners_) - listener->onNBSError(domain_name, info); + for (NetworkBearerSelectionInstance* listener : m_listeners_) { + listener->onNBSEvent(kEventSuccess); + } } -void NetworkBearerSelectionManager::makeDisconnectCallback( - const std::string& domain_name) { - LoggerD("enter"); +void NetworkBearerSelectionManager::makeDisconnectCallback() { + LoggerD("Entered"); + std::lock_guard lock(m_mutex_); - for (NetworkBearerSelectionListener* listener : m_listeners_) - listener->onNBSDisconnect(domain_name); + for (NetworkBearerSelectionInstance* listener : m_listeners_) { + listener->onNBSEvent(kEventDisconnected); + } } -void NetworkBearerSelectionManager::destroyProfileHandle() { - LoggerD("enter"); +void NetworkBearerSelectionManager::destroyProfileHandler() { + LoggerD("Entered"); + if (m_profile_handle_) { - connection_profile_destroy(m_profile_handle_); - m_profile_handle_ = nullptr; + if (CONNECTION_ERROR_NONE != connection_profile_destroy(m_profile_handle_)) { + LoggerE("Failed to destroy profile"); + } } } -RequestEventPtr NetworkBearerSelectionManager::getRequestEvent(NetworkBearerSelectionRequestEvent* event) { - LoggerD("enter"); - std::lock_guard lock(m_request_mutex_); - for (auto it = m_request_events_.begin(); it != m_request_events_.end(); it++) { - if (it->get() == event) { - LoggerD("Found object [%p]", it->get()); - RequestEventPtr ev = *it; - m_request_events_.erase(it); - return ev; - } +ErrorCode NetworkBearerSelectionManager::GetNBSErrorCode(int error_code) { + LoggerD("Entered"); + + switch (error_code) { + case CONNECTION_ERROR_NOT_SUPPORTED: + return ErrorCode::NOT_SUPPORTED_ERR; + default: + return ErrorCode::UNKNOWN_ERR; } - return nullptr; } -ReleaseEventPtr NetworkBearerSelectionManager::getReleaseEvent(NetworkBearerSelectionReleaseEvent* event) { - LoggerD("enter"); - std::lock_guard lock(m_release_mutex_); - for (auto it = m_release_events_.begin(); it != m_release_events_.end(); it++) { - if (it->get() == event) { - LoggerD("Found object [%p]", it->get()); - ReleaseEventPtr ev = *it; - m_release_events_.erase(it); - return ev; - } +bool NetworkBearerSelectionManager::createProfileHandler() { + LoggerD("Entered"); + + if (!m_connection_handle_) { + LoggerE("Connection handle is not created"); + return false; } - return nullptr; -} -common::ErrorCode NetworkBearerSelectionManager::GetNBSErrorCode(int error_code) { + int ret = CONNECTION_ERROR_NONE; + if (!m_profile_handle_) { + ret = connection_get_default_cellular_service_profile( + m_connection_handle_, CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET, &m_profile_handle_); - common::ErrorCode error = common::ErrorCode::UNKNOWN_ERR; + if (CONNECTION_ERROR_NONE != ret) { + LoggerE("Failed to get cellular profile"); + m_profile_handle_ = nullptr; + return false; + } + } - switch (error_code) { - case CONNECTION_ERROR_OPERATION_FAILED: - error = common::ErrorCode::UNKNOWN_ERR; - break; - case CONNECTION_ERROR_NOT_SUPPORTED: - error = common::ErrorCode::NOT_SUPPORTED_ERR; - break; - default: - error = common::ErrorCode::UNKNOWN_ERR; - break; + if (m_profile_name_.empty()) { + char* profile_name = nullptr; + ret = connection_profile_get_name(m_profile_handle_, &profile_name); + if (CONNECTION_ERROR_NONE != ret || nullptr == profile_name) { + LoggerE("Failed to get cellular profile name"); + return false; + } + + m_profile_name_ = profile_name; + free(profile_name); } - return error; + return true; } } // namespace networkbearerselection diff --git a/src/networkbearerselection/networkbearerselection_manager.h b/src/networkbearerselection/networkbearerselection_manager.h index 7e45a58..3edad48 100644 --- a/src/networkbearerselection/networkbearerselection_manager.h +++ b/src/networkbearerselection/networkbearerselection_manager.h @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -27,92 +26,59 @@ #include #include "common/platform_result.h" +#include "networkbearerselection_instance.h" namespace extension { namespace networkbearerselection { -enum class ConnectionState { - Unknown, - Connected, - Disconnected, - ConnectionFailed -}; - -enum class NetworkType { - Cellular, - Unknown -}; +struct NetworkBearerSelectionEvent; -struct NetworkBearerSelectionRequestEvent; -struct NetworkBearerSelectionReleaseEvent; - -typedef std::shared_ptr RequestEventPtr; -typedef std::shared_ptr ReleaseEventPtr; - -class NetworkBearerSelectionListener { - public: - virtual void onNBSSuccess(const std::string& domain_name) = 0; - virtual void onNBSError(const std::string& domain_name, - const std::string& info) = 0; - virtual void onNBSDisconnect(const std::string& domain_name) = 0; -}; +typedef std::shared_ptr EventPtr; +typedef std::function ReplyCallback; class NetworkBearerSelectionManager { public: - typedef std::function ReleaseReplyCallback; - void AddListener(NetworkBearerSelectionListener* listener); - void RemoveListener(NetworkBearerSelectionListener* listener); - - void requestRouteToHost(const std::string& domain_name); - common::PlatformResult releaseRouteToHost(const std::string& domain_name, - const ReleaseReplyCallback& reply_cb); + void AddListener(NetworkBearerSelectionInstance* listener); + void RemoveListener(NetworkBearerSelectionInstance* listener); + void callResultCallback(const ReplyCallback& reply, const common::PlatformResult result); + void requestRouteToHost(const std::string& domain_name, const ReplyCallback& reply); + void releaseRouteToHost(const std::string& domain_name, const ReplyCallback& reply); common::PlatformResult getCellularState(); - static NetworkBearerSelectionManager* GetInstance(); NetworkBearerSelectionManager(const NetworkBearerSelectionManager&) = delete; - NetworkBearerSelectionManager& operator=( - const NetworkBearerSelectionManager&) = delete; + NetworkBearerSelectionManager& operator=(const NetworkBearerSelectionManager&) = delete; private: - static void connection_state_changed_callback( - connection_profile_state_e state, - void* user_data); - static void connection_profile_opened_callback(connection_error_e result, - void* user_data); - static void connection_closed_callback(connection_error_e result, - void* user_data); - - void registStateChangeListener(const std::string& domain_name); - void deregistStateChangeListener(const std::string& domain_name); - - void makeSuccessCallback(const std::string& domain_name); - void makeErrorCallback(const std::string& domain_name, const char* info); - void makeErrorCallback(const std::string& domain_name, - const std::string& info); + static void connection_state_changed_callback(connection_profile_state_e state, void* user_data); + static void connection_opened_callback(connection_error_e result, void* user_data); + static void connection_closed_callback(connection_error_e result, void* user_data); + static void connection_closed_callback(connection_error_e result, common::PlatformResult); + + bool registerStateChangeListener(const std::string& domain_name); + bool deregisterStateChangeListener(const std::string& domain_name); + common::ErrorCode GetNBSErrorCode(int error_code); - void makeDisconnectCallback(const std::string& domain_name); - void destroyProfileHandle(); - RequestEventPtr getRequestEvent(NetworkBearerSelectionRequestEvent* event); - ReleaseEventPtr getReleaseEvent(NetworkBearerSelectionReleaseEvent* event); + void makeSuccessCallback(); + void makeDisconnectCallback(); + + bool removeDomainRoute(const std::map::iterator& iter); + bool createProfileHandler(); + void destroyProfileHandler(); NetworkBearerSelectionManager(); ~NetworkBearerSelectionManager(); - std::list m_listeners_; + std::list m_listeners_; connection_h m_connection_handle_; connection_profile_h m_profile_handle_; - std::list m_domain_names_; - std::vector m_request_events_; - std::vector m_release_events_; - ConnectionState m_connection_state_; - bool m_is_connection_open_; + std::string m_profile_name_; + std::map m_domain_names_; + bool m_is_connection_opened_; std::mutex m_mutex_; - std::mutex m_request_mutex_; - std::mutex m_release_mutex_; }; } // namespace networkbearerselection -- 2.7.4 From ac8ce401a74efb39acffa8f577318538191fc469 Mon Sep 17 00:00:00 2001 From: Piotr Kosko Date: Wed, 6 Sep 2017 13:13:08 +0200 Subject: [PATCH 12/16] [version] 2.0 Change-Id: I5904cd964c4449cdb22447654b38cd36d29fb622 Signed-off-by: Piotr Kosko --- 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 5a2092a..1b81071 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.99 +Version: 2.0 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries -- 2.7.4 From 7af77440715d19a2b5abff5a2c20b025e214dbe7 Mon Sep 17 00:00:00 2001 From: Jakub Skowron Date: Thu, 7 Sep 2017 16:41:04 +0200 Subject: [PATCH 13/16] [Systeminfo] Fix core dump in SystemInfoManager Cellular network listener was not unregistered, which caused core dump if network status changed after SystemInfoManager destructor. This is a hack, more robust solution should be developed. Change-Id: Id4d26492426028a87ebaf1109e4f7750dd10b7c4 Signed-off-by: Jakub Skowron --- src/systeminfo/systeminfo_manager.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/systeminfo/systeminfo_manager.cc b/src/systeminfo/systeminfo_manager.cc index a0bdc62..817698e 100644 --- a/src/systeminfo/systeminfo_manager.cc +++ b/src/systeminfo/systeminfo_manager.cc @@ -503,9 +503,9 @@ SysteminfoManager::~SysteminfoManager() { if (IsListenerRegistered(kPropertyIdDeviceOrientation)) { UnregisterDeviceOrientationListener(); } if (IsListenerRegistered(kPropertyIdLocale)) { UnregisterLocaleListener(); } if (IsListenerRegistered(kPropertyIdNetwork)) { UnregisterNetworkListener(); } - if (IsListenerRegistered(kPropertyIdWifiNetwork)) { UnregisterWifiNetworkListener(); } - if (IsListenerRegistered(kPropertyIdEthernetNetwork)) { UnregisterEthernetNetworkListener(); } - if (IsListenerRegistered(kPropertyIdCellularNetwork)) { UnregisterCellularNetworkListener(); } + if (IsListenerRegistered(kPropertyIdWifiNetwork)) { registered_listeners_.erase(kPropertyIdWifiNetwork)/*HACK*/; UnregisterWifiNetworkListener(); } + if (IsListenerRegistered(kPropertyIdEthernetNetwork)) { registered_listeners_.erase(kPropertyIdEthernetNetwork)/*HACK*/; UnregisterEthernetNetworkListener(); } + if (IsListenerRegistered(kPropertyIdCellularNetwork)) { registered_listeners_.erase(kPropertyIdCellularNetwork)/*HACK*/; UnregisterCellularNetworkListener(); } if (IsListenerRegistered(kPropertyIdPeripheral)) { UnregisterPeripheralListener(); } if (IsListenerRegistered(kPropertyIdMemory)) { UnregisterMemoryListener(); } if (IsListenerRegistered(kPropertyIdCameraFlash)) { UnregisterCameraFlashListener(); } -- 2.7.4 From 762d5afc4819bc156a13623a5da357363fb3e080 Mon Sep 17 00:00:00 2001 From: Lukasz Bardeli Date: Thu, 7 Sep 2017 17:25:18 +0200 Subject: [PATCH 14/16] [version] 2.01 Change-Id: I836d8a6a5ddcc6adfb07808d529ec1aa29ec1293 Signed-off-by: Lukasz Bardeli --- 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 1b81071..c06f63b 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: 2.0 +Version: 2.01 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries -- 2.7.4 From 40c39a402f6b7c1c22d2623ce5b5029630ae1315 Mon Sep 17 00:00:00 2001 From: Michal Bistyga Date: Thu, 7 Sep 2017 15:18:04 +0200 Subject: [PATCH 15/16] [CallHistory] Fix for find method [Bug]Multiple threads could access one vector, which resulted in crash. [Verification]Pass rate didn't change. Change-Id: I46a809c0df2965220b35a8e78389f2fdc8746c77 Signed-off-by: Michal Bistyga --- src/callhistory/callhistory.cc | 33 +++++++++++++++++++-------------- src/callhistory/callhistory.h | 21 +++++++++++++++++++-- src/callhistory/callhistory_utils.cc | 8 ++++++-- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/callhistory/callhistory.cc b/src/callhistory/callhistory.cc index 1d7a91e..d6fc1f6 100755 --- a/src/callhistory/callhistory.cc +++ b/src/callhistory/callhistory.cc @@ -98,10 +98,15 @@ void CallHistory::FindThread(const picojson::object& args, CallHistory* call_his LoggerD("Entered"); std::shared_ptr response{new picojson::value(picojson::object())}; - int phone_numbers = call_history->getPhoneNumbers().size(); + + int phone_numbers_size = 0; + { + CallHistory::LockedVector phone_numbers = call_history->getPhoneNumbers(); + phone_numbers_size = phone_numbers.size(); + } const double callback_id = args.find("callbackId")->second.get(); - if (phone_numbers == 0) { + if (0 == phone_numbers_size) { LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Phone numbers list is empty."), &response->get()); } else { @@ -247,12 +252,18 @@ void CallHistory::FindThread(const picojson::object& args, CallHistory* call_his void CallHistory::LoadPhoneNumbers(const picojson::object& args, CallHistory* call_history) { LoggerD("Entered"); - + CallHistory::LockedVector phone_numbers = call_history->getPhoneNumbers(); + if (0 != phone_numbers.size()) { + LoggerD("m_phone_numbers is already filled. Returning."); + return; + } char** cp_list = tel_get_cp_name_list(); + if (nullptr == cp_list){ + LoggerE("Failed to get cp_list"); + } if (cp_list) { unsigned int modem_num = 0; - std::vector& phone_numbers = call_history->getPhoneNumbers(); while (cp_list[modem_num]) { std::string n = ""; @@ -298,18 +309,12 @@ void CallHistory::LoadPhoneNumbers(const picojson::object& args, CallHistory* ca g_strfreev(cp_list); } - - FindThread(args, call_history); } void CallHistory::find(const picojson::object& args) { LoggerD("Entered"); - - if (m_phone_numbers.size() == 0) { - std::thread(LoadPhoneNumbers, args, this).detach(); - } else { - std::thread(FindThread, args, this).detach(); - } + std::thread(LoadPhoneNumbers, args, this).detach(); + std::thread(FindThread, args, this).detach(); } PlatformResult CallHistory::remove(const picojson::object& args) @@ -501,9 +506,9 @@ void CallHistory::removeAll(const picojson::object& args) data); } -std::vector& CallHistory::getPhoneNumbers() +CallHistory::LockedVector CallHistory::getPhoneNumbers() { - return m_phone_numbers; + return std::move(CallHistory::LockedVector{m_phone_numbers, m_phone_numbers_mutex}); } CallHistoryUtils& CallHistory::getUtils() diff --git a/src/callhistory/callhistory.h b/src/callhistory/callhistory.h index a366237..651f749 100755 --- a/src/callhistory/callhistory.h +++ b/src/callhistory/callhistory.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -40,7 +42,21 @@ class CallHistory explicit CallHistory(CallHistoryInstance& instance); ~CallHistory(); - std::vector& getPhoneNumbers(); + class LockedVector; + LockedVector getPhoneNumbers(); + //You can access m_phone_numbers only by getPhoneNumbers(). It will be available and locked in current scope. + //All section since calling getPhoneNumbers until end of scope will be critical section. + class LockedVector { + std::unique_lock guard; + typedef std::vector StringVector; + StringVector& vector; + LockedVector( StringVector& vector, std::mutex& lock ) : guard(lock), vector(vector) {}; + friend LockedVector CallHistory::getPhoneNumbers(); + public: + StringVector::size_type size() { return vector.size(); } + StringVector::value_type at(StringVector::size_type i) { return vector.at(i); } + void push_back(const StringVector::value_type& value) { vector.push_back(value); } + }; CallHistoryUtils& getUtils(); void find(const picojson::object& args); @@ -57,7 +73,8 @@ class CallHistory static void LoadPhoneNumbers(const picojson::object& args, CallHistory* call_history); bool m_is_listener_set; - std::vector m_phone_numbers; + std::mutex m_phone_numbers_mutex; + std::vector m_phone_numbers; //See LockedVector CallHistoryInstance& instance_; CallHistoryUtils utils_; }; diff --git a/src/callhistory/callhistory_utils.cc b/src/callhistory/callhistory_utils.cc index 1dcf72a..23fddb2 100755 --- a/src/callhistory/callhistory_utils.cc +++ b/src/callhistory/callhistory_utils.cc @@ -226,8 +226,11 @@ void CallHistoryUtils::parseCallingParty(contacts_record_h *record, picojson::ob { LoggerD("Entered"); - const std::vector& phone_numbers = history_.getPhoneNumbers(); - int sim_count = phone_numbers.size(); + int sim_count = 0; + { + CallHistory::LockedVector phone_numbers = history_.getPhoneNumbers(); + sim_count = phone_numbers.size(); + } int sim_index; int ret = contacts_record_get_int(*record, _contacts_phone_log.sim_slot_no, &sim_index); @@ -238,6 +241,7 @@ void CallHistoryUtils::parseCallingParty(contacts_record_h *record, picojson::ob if (sim_index >= sim_count) { LoggerE("sim slot no. [%d] is out of count %d", sim_index, sim_count); } else if (sim_index > 0) { + CallHistory::LockedVector phone_numbers = history_.getPhoneNumbers(); obj[STR_CALLING_PARTY] = picojson::value(phone_numbers.at(sim_index)); } } -- 2.7.4 From 5eecfa381752521463596a310d75c0e448d4c9cf Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Thu, 14 Sep 2017 12:27:32 +0200 Subject: [PATCH 16/16] [widgetservice] Check if widget_id is not null [verification] TCT pass rate 100% on TM1 [svace] 289591 Change-Id: I03b2fd5914965e3c52c69fef7bdb2fc3c73c99a5 Signed-off-by: Rafal Walczyna --- src/widgetservice/widgetservice_instance.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgetservice/widgetservice_instance.cc b/src/widgetservice/widgetservice_instance.cc index b5bc29c..eb8070d 100644 --- a/src/widgetservice/widgetservice_instance.cc +++ b/src/widgetservice/widgetservice_instance.cc @@ -140,7 +140,9 @@ int WidgetLifecycleCb(const char* widget_id, widget_lifecycle_event_e lifecycle_ obj.insert(std::make_pair(kEvent, picojson::value(WidgetServiceUtils::FromEventType(lifecycle_event)))); - instance->CallWidgetLifecycleListener(widget_id, response); + if (nullptr != widget_id) { + instance->CallWidgetLifecycleListener(widget_id, response); + } return WIDGET_ERROR_NONE; } -- 2.7.4