VERYGOOD : 'ACCURACY_VERYGOOD'
};
+var SensorStates = {
+ NOT_STARTED : 0,
+ STARTING : 1,
+ STARTED : 2
+};
+
+
// helper class for sensor listeners
var SensorListener = function (type, constructor) {
this.sensorType = type;
- this.isStarted = false;
+ this.state = SensorStates.NOT_STARTED;
this.callback = undefined;
this.constructor = constructor;
};
};
SensorListener.prototype.start = function (successCallback, errorCallback) {
- if (!this.isStarted) {
+ if (SensorStates.STARTED != this.state) {
// sensor not started
+ this.state = SensorStates.STARTING;
var thisObject = this;
native_.call('Sensor_start', {'sensorType' : thisObject.sensorType},
function(result) {
errorCallback(native_.getErrorObject(result));
}
} else {
- thisObject.isStarted = true;
+ thisObject.state = SensorStates.STARTED;
successCallback();
}
}
};
SensorListener.prototype.stop = function () {
- if (this.isStarted) {
+ if (SensorStates.NOT_STARTED != this.state) {
var result = native_.callSync('Sensor_stop', {'sensorType' : this.sensorType});
if (native_.isFailure(result)) {
throw native_.getErrorObject(result);
}
- this.isStarted = false;
+ this.state = SensorStates.NOT_STARTED;
}
};
SensorListener.prototype.getData = function (successCallback, errorCallback) {
var thisObj = this;
- if (!thisObj.isStarted) {
+ if (SensorStates.STARTED != this.state) {
setTimeout(function() {
if (!T_.isNullOrUndefined(errorCallback)) {
errorCallback(new WebAPIException(
private:
static void SensorCallback(sensor_h sensor, sensor_event_s* event, void* user_data);
+ PlatformResult AddDelayedStartSuccessCb(const std::function<void()>& successCb);
sensor_type_e type_enum_;
EventComparator comparator_;
common::optional<bool> is_supported_;
SensorInstance& instance_;
std::mutex initialization_mutex_;
+ bool is_change_listener_set_;
+ std::vector<std::function<void()>> delayed_success_callbacks_;
};
SensorData::SensorData(SensorInstance& instance, sensor_type_e type_enum,
sensor_value_count_(sensor_value_count),
handle_(nullptr),
listener_(nullptr),
- previous_event_(),
- instance_(instance) {
+ previous_event_{0,0,0,-FLT_MAX}, // setting dumb non-zero value to differ init value from
+ // "good" zero values from sensor
+ instance_(instance),
+ is_change_listener_set_(false) {
type_to_string_map.insert(std::make_pair(type_enum, name));
string_to_type_map.insert(std::make_pair(name, type_enum));
LoggerD("Entered: %s", type_to_string_map[that->type()].c_str());
+ if (!that->delayed_success_callbacks_.empty()) {
+ for_each(that->delayed_success_callbacks_.begin(), that->delayed_success_callbacks_.end(),
+ [](std::function<void()>& callback) {
+ LoggerD("Calling delayed start succcess callback");
+ callback();
+ });
+ that->delayed_success_callbacks_.erase(that->delayed_success_callbacks_.begin(),
+ that->delayed_success_callbacks_.end());
+ if (!that->is_change_listener_set_) {
+ LoggerD("unregistering temporary listener used to delay start success callback");
+ int ret = sensor_listener_unset_event_cb(that->listener_);
+ if (SENSOR_ERROR_NONE != ret) {
+ LoggerE("unsetting temporary listener failed: %d", ret);
+ }
+ }
+ }
+
if (!that->UpdateEvent(event)) {
// value didn't change - ignore
return;
}
}
-struct DelaySuccessCbData {
- DelaySuccessCbData(const std::shared_ptr<picojson::value> &_result)
- : result(_result),
- delay_success_cb_listener(nullptr) {
- }
+PlatformResult SensorData::AddDelayedStartSuccessCb(const std::function<void()>& successCb) {
+ LoggerD("Entered");
+ delayed_success_callbacks_.push_back(successCb);
- const std::shared_ptr<picojson::value> result;
- sensor_listener_h delay_success_cb_listener;
- std::function<void(const std::shared_ptr<picojson::value>&)> report_result;
-};
+ if (!is_change_listener_set_) {
+ LoggerD("Adding temporary listener by hand");
+ int ret = sensor_listener_set_event_cb(listener_, 10, // as small interval as possible for tmp listener
+ SensorCallback, this);
+ if (SENSOR_ERROR_NONE != ret) {
+ LoggerE("sensor_listener_set_event_cb returned error: %d", ret);
+ return GetSensorPlatformResult(ret, "sensor_listener_set_event_cb");
+ }
+ } else {
+ LoggerD("Temporary listener is not needed");
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
PlatformResult SensorData::Start(const std::shared_ptr<picojson::value>& result,
const std::function<void(const std::shared_ptr<picojson::value>&)>& report_result) {
return res;
}
- sensor_listener_h delay_success_cb_listener = nullptr;
- int ret = sensor_create_listener(handle_, &delay_success_cb_listener);
- if (SENSOR_ERROR_NONE != ret) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR,
- "Failed to create listener.",
- ("sensor_create_listener() error: %d, message: %s", ret, get_error_message(ret)));
- }
-
- ret = sensor_listener_set_option(delay_success_cb_listener, SENSOR_OPTION_ALWAYS_ON);
- if (SENSOR_ERROR_NONE != ret) {
- sensor_destroy_listener(delay_success_cb_listener);
- LoggerE("sensor_listener_set_option : %d", ret);
- return GetSensorPlatformResult(ret, "sensor_listener_set_option");
- }
-
- DelaySuccessCbData *data = new DelaySuccessCbData(result);
- data->delay_success_cb_listener = delay_success_cb_listener;
- data->report_result = report_result;
-
- ret = sensor_listener_set_event_cb(delay_success_cb_listener, 10,//as less as possible
- [](sensor_h sensor, sensor_event_s* event, void* user_data) -> void {
- LoggerD("Enter");
- DelaySuccessCbData *data = static_cast<DelaySuccessCbData*>(user_data);
- if (nullptr == data) {
- LoggerE("data equal to nullptr");
- return;
- }
-
- SCOPE_EXIT {
- delete data;
- };
-
- sensor_listener_h listener = data->delay_success_cb_listener;
- ReportSuccess(data->result->get<picojson::object>());
- data->report_result(data->result);
-
- int ret = sensor_listener_unset_event_cb(listener);
- if (SENSOR_ERROR_NONE != ret) {
- LoggerE("sensor_listener_unset_event_cb : %d", ret);
- }
-
- ret = sensor_destroy_listener(listener);
- if (SENSOR_ERROR_NONE != ret) {
- LoggerE("sensor_listener_unset_event_cb : %d", ret);
- }
- }, data);
-
- if (SENSOR_ERROR_NONE != ret) {
- sensor_destroy_listener(delay_success_cb_listener);
- delete data;
- LoggerE("sensor_listener_set_event_cb : %d", ret);
- return GetSensorPlatformResult(ret, "sensor_listener_set_event_cb");
- }
-
- ret = sensor_listener_start(delay_success_cb_listener);
- if (SENSOR_ERROR_NONE != ret) {
- sensor_listener_unset_event_cb(delay_success_cb_listener);
- sensor_destroy_listener(delay_success_cb_listener);
- delete data;
- LoggerE("sensor_listener_start : %d", ret);
- return GetSensorPlatformResult(ret, "sensor_listener_start");
+ auto delayed_success_callback = [this, result, report_result] () {
+ LoggerD("Delayed success callback");
+ ReportSuccess(result->get<picojson::object>());
+ report_result(result);
+ };
+ res = AddDelayedStartSuccessCb(delayed_success_callback);
+ if(!res) {
+ return res;
}
sensor_listener_set_option(listener_, SENSOR_OPTION_ALWAYS_ON);
- ret = sensor_listener_start(listener_);
+ int ret = sensor_listener_start(listener_);
if (SENSOR_ERROR_NONE != ret) {
- sensor_listener_unset_event_cb(delay_success_cb_listener);
- sensor_destroy_listener(delay_success_cb_listener);
- delete data;
LoggerE("sensor_listener_start : %d", ret);
return GetSensorPlatformResult(ret, "sensor_listener_start");
}
return GetSensorPlatformResult(ret, "sensor_listener_stop");
}
+ // reseting delayed success callbacks flag and saved event values
+ previous_event_ = {0,0,0,-FLT_MAX}; // setting dumb non-zero value to differ init value from
+ // "good" zero values from sensor
+ delayed_success_callbacks_.erase(delayed_success_callbacks_.begin(),
+ delayed_success_callbacks_.end());
+
return PlatformResult(ErrorCode::NO_ERROR);
}
return GetSensorPlatformResult(ret, "sensor_listener_set_event_cb");
}
+ is_change_listener_set_ = true;
+
return PlatformResult(ErrorCode::NO_ERROR);
}
return GetSensorPlatformResult(ret, "sensor_listener_unset_event_cb");
}
+ is_change_listener_set_ = false;
+
return PlatformResult(ErrorCode::NO_ERROR);
}