From e1c5cc47ab6306621e47d84054873cb9fdba90ee Mon Sep 17 00:00:00 2001
From: Piotr Kosko
Date: Mon, 16 Feb 2015 07:25:33 +0100
Subject: [PATCH] [Sensor] Implementation of listeners
Change-Id: I7a5ad86471814f9dc60f217213451fd1be4b4b6b
Signed-off-by: Piotr Kosko
---
src/sensor/sensor_api.js | 71 +++++++++++----
src/sensor/sensor_service.cc | 166 +++++++++++++++++++++++++++++------
2 files changed, 197 insertions(+), 40 deletions(-)
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) {
--
2.34.1