From: Piotr Kosko Date: Mon, 16 Feb 2015 06:25:33 +0000 (+0100) Subject: [Sensor] Implementation of listeners X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~430 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e1c5cc47ab6306621e47d84054873cb9fdba90ee;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Sensor] Implementation of listeners Change-Id: I7a5ad86471814f9dc60f217213451fd1be4b4b6b Signed-off-by: Piotr Kosko --- diff --git a/src/sensor/sensor_api.js b/src/sensor/sensor_api.js index 6b54a5bb..b179bddc 100644 --- a/src/sensor/sensor_api.js +++ b/src/sensor/sensor_api.js @@ -40,6 +40,25 @@ var _startedSensors = { }; var _isChecked = false; +var _sensorListeners = { + 'LIGHT' : { callback : undefined, constructor : undefined }, + 'MAGNETIC' : { callback : undefined, constructor : undefined }, + 'PRESSURE' : { callback : undefined, constructor : undefined }, + 'PROXIMITY' : { callback : undefined, constructor : undefined }, + 'ULTRAVIOLET' : { callback : undefined, constructor : undefined } +} + +var _listener = function(object) { + if (_sensorListeners[object.sensorType].callback) { + _sensorListeners[object.sensorType].callback( + new _sensorListeners[object.sensorType].constructor(object)); + } +}; + +var SENSOR_CHANGED_LISTENER = 'SensorChangedListener'; +native_.addListener(SENSOR_CHANGED_LISTENER, _listener); + + function getAvailableSensors() { var result = native_.callSync('SensorService_getAvailableSensors', {}); if (native_.isFailure(result)) { @@ -68,15 +87,15 @@ SensorService.prototype.getDefaultSensor = function() { var index = _supportedSensors.indexOf(args.type); if (index === -1) { throw new tizen.WebAPIException(tizen.WebAPIException.NOT_SUPPORTED_ERR, 'Not supported.'); - } else if (_supportedSensors[index] === 'LIGHT') { + } else if (_supportedSensors[index] === SensorType.LIGHT) { return new LightSensor(); - } else if (_supportedSensors[index] === 'MAGNETIC') { + } else if (_supportedSensors[index] === SensorType.MAGNETIC) { return new MagneticSensor(); - } else if (_supportedSensors[index] === 'PRESSURE') { + } else if (_supportedSensors[index] === SensorType.PRESSURE) { return new PressureSensor(); - } else if (_supportedSensors[index] === 'PROXIMITY') { + } else if (_supportedSensors[index] === SensorType.PROXIMITY) { return new ProximitySensor(); - } else if (_supportedSensors[index] === 'ULTRAVIOLET') { + } else if (_supportedSensors[index] === SensorType.ULTRAVIOLET) { return new UltravioletSensor(); } }; @@ -133,9 +152,12 @@ Sensor.prototype.start = function() { }; Sensor.prototype.stop = function() { - var result = native_.callSync('Sensor_stop', {'sensorType' : this.sensorType}); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); + if (_startedSensors[this.sensorType]) { + var result = native_.callSync('Sensor_stop', {'sensorType' : this.sensorType}); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + _startedSensors[this.sensorType] = false; } }; @@ -145,18 +167,26 @@ Sensor.prototype.setChangeListener = function() { name : 'successCallback', type: types_.FUNCTION } - ]); + ]); - var result = native_.callSync('Sensor_setChangeListener', {'sensorType' : this.sensorType}); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); + if (!_sensorListeners[this.sensorType].callback) { + //call platform only if there was no listener registered + var result = native_.callSync('Sensor_setChangeListener', {'sensorType' : this.sensorType}); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } } + _sensorListeners[this.sensorType].callback = args.successCallback; }; Sensor.prototype.unsetChangeListener = function() { - var result = native_.callSync('Sensor_unsetChangeListener', {'sensorType' : this.sensorType}); - if (native_.isFailure(result)) { - throw native_.getErrorObject(result); + if (_sensorListeners[this.sensorType].callback) { + //unregister in platform only if there is callback registered + _sensorListeners[this.sensorType].callback = undefined; + var result = native_.callSync('Sensor_unsetChangeListener', {'sensorType' : this.sensorType}); + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } } }; @@ -402,6 +432,8 @@ SensorLightData.prototype = new SensorData(); SensorLightData.prototype.constructor = SensorData; +_sensorListeners[SensorType.LIGHT].constructor = SensorLightData; + //// SensorMagneticData var SensorMagneticData = function(data) { SensorData.call(this); @@ -417,6 +449,8 @@ SensorMagneticData.prototype = new SensorData(); SensorMagneticData.prototype.constructor = SensorData; +_sensorListeners[SensorType.MAGNETIC].constructor = SensorMagneticData; + //// SensorPressureData var SensorPressureData = function(data) { SensorData.call(this); @@ -429,6 +463,8 @@ SensorPressureData.prototype = new SensorData(); SensorPressureData.prototype.constructor = SensorData; +_sensorListeners[SensorType.PRESSURE].constructor = SensorPressureData; + //// SensorProximityData var SensorProximityData = function(data) { SensorData.call(this); @@ -441,6 +477,8 @@ SensorProximityData.prototype = new SensorData(); SensorProximityData.prototype.constructor = SensorData; +_sensorListeners[SensorType.PROXIMITY].constructor = SensorProximityData; + //// SensorUltravioletData var SensorUltravioletData = function(data) { SensorData.call(this); @@ -449,9 +487,12 @@ var SensorUltravioletData = function(data) { }); }; + SensorUltravioletData.prototype = new SensorData(); SensorUltravioletData.prototype.constructor = SensorData; +_sensorListeners[SensorType.ULTRAVIOLET].constructor = SensorUltravioletData; + // Exports exports = new SensorService(); diff --git a/src/sensor/sensor_service.cc b/src/sensor/sensor_service.cc index 87754d5e..93238f84 100644 --- a/src/sensor/sensor_service.cc +++ b/src/sensor/sensor_service.cc @@ -6,6 +6,7 @@ #include #include +#include #include "common/task-queue.h" #include "common/logger.h" @@ -41,6 +42,14 @@ static std::map string_to_type_map = { {"ULTRAVIOLET", SENSOR_ULTRAVIOLET} }; +static sensor_event_s previous_light_event; +static sensor_event_s previous_magnetic_event; +static sensor_event_s previous_pressure_event; +static sensor_event_s previous_proximity_event; +static sensor_event_s previous_ultraviolet_event; + +std::mutex init_mutex; + static std::string GetAccuracyString(int accuracy) { LoggerD("Entered"); switch (static_cast(accuracy)) { @@ -56,6 +65,10 @@ static std::string GetAccuracyString(int accuracy) { return "ACCURACY_UNDEFINED"; } } + +static const std::string kSensorTypeTag = "sensorType"; +static const std::string kListenerId = "listenerId"; +static const std::string kSensorChangedListener = "SensorChangedListener"; } SensorService::SensorService() { @@ -150,7 +163,7 @@ void SensorService::SensorStart(const picojson::value& args, picojson::object& o CHECK_EXIST(args, "callbackId", out) int callback_id = static_cast(args.get("callbackId").get()); const std::string type_str = - args.contains("sensorType") ? args.get("sensorType").get() : ""; + args.contains(kSensorTypeTag) ? args.get(kSensorTypeTag).get() : ""; LoggerD("input type: %s" , type_str.c_str()); sensor_type_e type_enum = string_to_type_map[type_str]; @@ -196,44 +209,79 @@ void SensorService::SensorStart(const picojson::value& args, picojson::object& o void SensorService::SensorStop(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); const std::string type_str = - args.contains("sensorType") ? args.get("sensorType").get() : ""; + args.contains(kSensorTypeTag) ? args.get(kSensorTypeTag).get() : ""; LoggerD("input type: %s" , type_str.c_str()); sensor_type_e type_enum = string_to_type_map[type_str]; PlatformResult res = CheckSensorInitialization(type_enum); SensorData* sensor_data = GetSensorStruct(type_enum); - //TODO fill + + if (!sensor_data) { + LoggerD("Sensor data is null"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Sensor data is null"), &out); + return; + } + + int ret = sensor_listener_stop(sensor_data->listener); + if (ret != SENSOR_ERROR_NONE) { + LOGE("ret : %d", ret); + ReportError(GetSensorPlatformResult(ret, "sensor_listener_stop"), &out); + } } void SensorService::SensorSetChangeListener(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); const std::string type_str = - args.contains("sensorType") ? args.get("sensorType").get() : ""; + args.contains(kSensorTypeTag) ? args.get(kSensorTypeTag).get() : ""; LoggerD("input type: %s" , type_str.c_str()); sensor_type_e type_enum = string_to_type_map[type_str]; PlatformResult res = CheckSensorInitialization(type_enum); SensorData* sensor_data = GetSensorStruct(type_enum); - //TODO fill + + if (!sensor_data) { + LoggerD("Sensor data is null"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Sensor data is null"), &out); + return; + } + + int ret = sensor_listener_set_event_cb( + sensor_data->listener, 100, GetCallbackFunction(type_enum), this); + if (ret != SENSOR_ERROR_NONE) { + LOGE("ret : %d", ret); + ReportError(GetSensorPlatformResult(ret, "sensor_listener_set_event_cb"), &out); + } } void SensorService::SensorUnsetChangeListener(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); const std::string type_str = - args.contains("sensorType") ? args.get("sensorType").get() : ""; + args.contains(kSensorTypeTag) ? args.get(kSensorTypeTag).get() : ""; LoggerD("input type: %s" , type_str.c_str()); sensor_type_e type_enum = string_to_type_map[type_str]; PlatformResult res = CheckSensorInitialization(type_enum); SensorData* sensor_data = GetSensorStruct(type_enum); - //TODO fill + + if (!sensor_data) { + LoggerD("Sensor data is null"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Sensor data is null"), &out); + return; + } + + int ret = sensor_listener_unset_event_cb(sensor_data->listener); + if (ret != SENSOR_ERROR_NONE) { + LOGE("ret : %d", ret); + ReportError(GetSensorPlatformResult(ret, "sensor_listener_unset_event_cb"), &out); + } } PlatformResult SensorService::CheckSensorInitialization(sensor_type_e type_enum) { LoggerD("Entered"); + std::lock_guard lock(init_mutex); SensorData* sensor_data = NULL; switch(type_enum) { @@ -288,42 +336,110 @@ SensorService::SensorData* SensorService::GetSensorStruct(sensor_type_e type_enu } } +void PrepareCallback(const std::string& sensor_type, picojson::object& out) { + out[kListenerId] = picojson::value(kSensorChangedListener); + out[kSensorTypeTag] = picojson::value(sensor_type); +} + void SensorLightCallback(sensor_h sensor, sensor_event_s *event, void *user_data) { - float lux = event->values[0]; - LoggerD("enter %f", lux); - //TODO fill + if (previous_light_event.values[0] == event->values[0]) { + //value didn't change - ignore + return; + } + previous_light_event = *event; + float lux = event->values[0]; + LoggerD("passing %f", lux); + picojson::value result = picojson::value(picojson::object()); + picojson::object& object = result.get(); + object["lightLevel"] = + picojson::value(static_cast(event->values[0])); + PrepareCallback("LIGHT", object); + SensorInstance::GetInstance().PostMessage(result.serialize().c_str()); } void SensorMagneticCallback(sensor_h sensor, sensor_event_s *event, void *user_data) { - sensor_data_accuracy_e accuracy = static_cast(event->accuracy); - float x = event ->values[0]; - float y = event ->values[1]; - float z = event ->values[2]; - LoggerD("enter [ %f , %f , %f ] [ %d ]",x, y, z, accuracy); - //TODO fill + if (previous_magnetic_event.values[0] == event->values[0] && + previous_magnetic_event.values[1] == event->values[1] && + previous_magnetic_event.values[2] == event->values[2] && + previous_magnetic_event.accuracy == event->accuracy) { + //value didn't change - ignore + return; + } + previous_magnetic_event = *event; + sensor_data_accuracy_e accuracy = static_cast(event->accuracy); + float x = event ->values[0]; + float y = event ->values[1]; + float z = event ->values[2]; + LoggerD("passing [ %f , %f , %f ] [ %d ]",x, y, z, accuracy); + + picojson::value result = picojson::value(picojson::object()); + picojson::object& object = result.get(); + object["x"] = + picojson::value(static_cast(event->values[0])); + object["y"] = + picojson::value(static_cast(event->values[1])); + object["z"] = + picojson::value(static_cast(event->values[2])); + object["accuracy"] = + picojson::value(GetAccuracyString(event->accuracy)); + PrepareCallback("MAGNETIC", object); + SensorInstance::GetInstance().PostMessage(result.serialize().c_str()); } void SensorPressureCallback(sensor_h sensor, sensor_event_s *event, void *user_data) { - float pressure = event->values[0]; - LoggerD("enter %f", pressure); - //TODO fill + if (previous_pressure_event.values[0] == event->values[0]) { + //value didn't change - ignore + return; + } + previous_pressure_event = *event; + float pressure = event->values[0]; + LoggerD("enter %f", pressure); + + picojson::value result = picojson::value(picojson::object()); + picojson::object& object = result.get(); + object["pressure"] = + picojson::value(static_cast(event->values[0])); + PrepareCallback("PRESSURE", object); + SensorInstance::GetInstance().PostMessage(result.serialize().c_str()); } void SensorProximityCallback(sensor_h sensor, sensor_event_s *event, void *user_data) { - float distance = event->values[0]; - LoggerD("enter %f", distance); - //TODO fill + if (previous_proximity_event.values[0] == event->values[0]) { + //value didn't change - ignore + return; + } + previous_proximity_event = *event; + float distance = event->values[0]; + LoggerD("enter %f", distance); + + picojson::value result = picojson::value(picojson::object()); + picojson::object& object = result.get(); + int state = static_cast(event->values[0]); + object["proximityState"] = picojson::value(state ? "NEAR" : "FAR"); + PrepareCallback("PROXIMITY", object); + SensorInstance::GetInstance().PostMessage(result.serialize().c_str()); } void SensorUltravioletCallback(sensor_h sensor, sensor_event_s *event, void *user_data) { - float index = event->values[0]; - LoggerD("enter %f", index); - //TODO fill + if (previous_ultraviolet_event.values[0] == event->values[0]) { + //value didn't change - ignore + return; + } + previous_ultraviolet_event = *event; + float index = event->values[0]; + LoggerD("enter %f", index); + + picojson::value result = picojson::value(picojson::object()); + picojson::object& object = result.get(); + object["ultravioletLevel"] = + picojson::value(static_cast(event->values[0])); + PrepareCallback("ULTRAVIOLET", object); + SensorInstance::GetInstance().PostMessage(result.serialize().c_str()); } CallbackPtr SensorService::GetCallbackFunction(sensor_type_e type_enum) {