diff --git a/packages/sensors_plus/tizen/src/device_sensor.cc b/packages/sensors_plus/tizen/src/device_sensor.cc new file mode 100644 index 000000000..2788ef2df --- /dev/null +++ b/packages/sensors_plus/tizen/src/device_sensor.cc @@ -0,0 +1,112 @@ +// Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device_sensor.h" + +#include "log.h" + +namespace { + +sensor_type_e ToTizenSensorType(const SensorType &sensor_type) { + switch (sensor_type) { + case SensorType::kAccelerometer: + return SENSOR_ACCELEROMETER; + case SensorType::kGyroscope: + return SENSOR_GYROSCOPE; + case SensorType::kUserAccel: + default: + return SENSOR_LINEAR_ACCELERATION; + } +} + +} // namespace + +DeviceSensor::DeviceSensor(SensorType sensor_type) + : sensor_type_(sensor_type) {} + +DeviceSensor::~DeviceSensor() { + if (is_listening_) { + StopListen(); + } + + if (listener_) { + sensor_destroy_listener(listener_); + listener_ = nullptr; + } +} + +bool DeviceSensor::StartListen(SensorEventCallback callback) { + if (is_listening_) { + LOG_WARN("Already listening."); + last_error_ = SENSOR_ERROR_OPERATION_FAILED; + return false; + } + + sensor_h sensor; + int ret = sensor_get_default_sensor(ToTizenSensorType(sensor_type_), &sensor); + if (ret != SENSOR_ERROR_NONE) { + LOG_ERROR("Failed to get default sensor: %s", get_error_message(ret)); + last_error_ = ret; + return false; + } + + ret = sensor_create_listener(sensor, &listener_); + if (ret != SENSOR_ERROR_NONE) { + LOG_ERROR("Failed to create listener: %s", get_error_message(ret)); + last_error_ = ret; + return false; + } + + ret = sensor_listener_set_event_cb( + listener_, 60, + [](sensor_h sensor, sensor_event_s *event, void *user_data) { + auto *self = static_cast(user_data); + SensorEvent sensor_event; + for (int i = 0; i < event->value_count; i++) { + sensor_event.push_back(event->values[i]); + } + self->callback_(sensor_event); + }, + this); + if (ret != SENSOR_ERROR_NONE) { + LOG_ERROR("Failed to set event callback: %s", get_error_message(ret)); + last_error_ = ret; + return false; + } + + ret = sensor_listener_start(listener_); + if (ret != SENSOR_ERROR_NONE) { + LOG_ERROR("Failed to start listener: %s", get_error_message(ret)); + last_error_ = ret; + return false; + } + + callback_ = callback; + is_listening_ = true; + + return true; +} + +void DeviceSensor::StopListen() { + if (!is_listening_) { + LOG_WARN("Already canceled."); + return; + } + + int ret = sensor_listener_stop(listener_); + if (ret != SENSOR_ERROR_NONE) { + LOG_ERROR("Failed to stop listener: %s", get_error_message(ret)); + last_error_ = ret; + return; + } + + is_listening_ = false; + + ret = sensor_listener_unset_event_cb(listener_); + if (ret != SENSOR_ERROR_NONE) { + LOG_ERROR("Failed to unset event callback: %s", get_error_message(ret)); + last_error_ = ret; + return; + } +} diff --git a/packages/sensors_plus/tizen/src/device_sensor.h b/packages/sensors_plus/tizen/src/device_sensor.h new file mode 100644 index 000000000..215692c10 --- /dev/null +++ b/packages/sensors_plus/tizen/src/device_sensor.h @@ -0,0 +1,42 @@ +// Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_PLUGIN_DEVICE_SENSOR_H_ +#define FLUTTER_PLUGIN_DEVICE_SENSOR_H_ + +#include +#include + +#include +#include +#include + +enum class SensorType { kAccelerometer, kGyroscope, kUserAccel }; + +typedef std::vector SensorEvent; +typedef std::function SensorEventCallback; + +class DeviceSensor { + public: + DeviceSensor(SensorType sensor_type); + ~DeviceSensor(); + + int GetLastError() { return last_error_; } + + std::string GetLastErrorString() { return get_error_message(last_error_); } + + bool StartListen(SensorEventCallback callback); + + void StopListen(); + + private: + SensorType sensor_type_; + sensor_listener_h listener_ = nullptr; + bool is_listening_ = false; + int last_error_ = TIZEN_ERROR_NONE; + + SensorEventCallback callback_ = nullptr; +}; + +#endif // FLUTTER_PLUGIN_DEVICE_SENSOR_H_ diff --git a/packages/sensors_plus/tizen/src/sensors_plus_plugin.cc b/packages/sensors_plus/tizen/src/sensors_plus_plugin.cc index 796e9f350..32976982e 100644 --- a/packages/sensors_plus/tizen/src/sensors_plus_plugin.cc +++ b/packages/sensors_plus/tizen/src/sensors_plus_plugin.cc @@ -3,221 +3,88 @@ #include #include #include -#include #include #include -#include -#include -#include -#include -#include +#include "device_sensor.h" -#include "log.h" +typedef flutter::EventChannel FlEventChannel; +typedef flutter::EventSink FlEventSink; +typedef flutter::StreamHandler FlStreamHandler; +typedef flutter::StreamHandlerError + FlStreamHandlerError; -class Listener { +class DeviceSensorStreamHandler : public FlStreamHandler { public: - Listener( - std::unique_ptr> &&event_sink) - : event_sink_(std::move(event_sink)) {} - - bool Init(sensor_type_e type) { - sensor_h sensor; - int ret = sensor_get_default_sensor(type, &sensor); - if (ret != SENSOR_ERROR_NONE) { - LOG_ERROR("%s", get_error_message(ret)); - return false; - } - ret = sensor_create_listener(sensor, &listener_); - if (ret != SENSOR_ERROR_NONE) { - LOG_ERROR("%s", get_error_message(ret)); - return false; - } - return true; - } - - void Listen() { - if (is_listening_) { - LOG_ERROR("Already listening!"); - return; - } - - int ret = sensor_listener_set_event_cb( - listener_, 60, - [](sensor_h sensor, sensor_event_s *event, void *user_data) { - Listener *s = (Listener *)user_data; - std::vector list; - for (int i = 0; i < event->value_count; i++) { - list.push_back(event->values[i]); - } - flutter::EncodableValue value(list); - s->event_sink_->Success(value); - }, - this); - - if (ret != SENSOR_ERROR_NONE) { - LOG_ERROR("%s", get_error_message(ret)); - return; - } - ret = sensor_listener_start(listener_); - if (ret != SENSOR_ERROR_NONE) { - LOG_ERROR("%s", get_error_message(ret)); - return; - } - - is_listening_ = true; - } + DeviceSensorStreamHandler(SensorType type) : sensor_(type) {} - void Cancel() { - if (!is_listening_) { - LOG_ERROR("Already canceled!"); - return; - } - int ret = sensor_listener_stop(listener_); - if (ret != SENSOR_ERROR_NONE) { - LOG_ERROR("%s", get_error_message(ret)); - return; - } - - ret = sensor_listener_unset_event_cb(listener_); - if (ret != SENSOR_ERROR_NONE) { - LOG_ERROR("%s", get_error_message(ret)); - return; + protected: + std::unique_ptr OnListenInternal( + const flutter::EncodableValue *arguments, + std::unique_ptr &&events) override { + events_ = std::move(events); + + SensorEventCallback callback = [this](SensorEvent sensor_event) -> void { + events_->Success(flutter::EncodableValue(sensor_event)); + }; + if (!sensor_.StartListen(callback)) { + return std::make_unique( + std::to_string(sensor_.GetLastError()), sensor_.GetLastErrorString(), + nullptr); } - is_listening_ = false; + return nullptr; } - virtual ~Listener() { - if (is_listening_) { - Cancel(); - } - if (listener_) { - int ret = sensor_destroy_listener(listener_); - if (ret != SENSOR_ERROR_NONE) { - LOG_ERROR("%s", get_error_message(ret)); - } - } + std::unique_ptr OnCancelInternal( + const flutter::EncodableValue *arguments) override { + sensor_.StopListen(); + events_.reset(); + return nullptr; } - protected: - std::unique_ptr> event_sink_; - sensor_listener_h listener_{nullptr}; - bool is_listening_{false}; + private: + DeviceSensor sensor_; + std::unique_ptr events_; }; class SensorsPlusPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { - LOG_DEBUG("RegisterWithRegistrar"); auto plugin = std::make_unique(); plugin->SetupEventChannels(registrar); registrar->AddPlugin(std::move(plugin)); } - SensorsPlusPlugin() { LOG_DEBUG("Create"); } + SensorsPlusPlugin() {} - virtual ~SensorsPlusPlugin() { LOG_DEBUG("Destroy"); } + virtual ~SensorsPlusPlugin() {} private: void SetupEventChannels(flutter::PluginRegistrar *registrar) { - accelerometer_channel_ = - std::make_unique>( - registrar->messenger(), - "dev.fluttercommunity.plus/sensors/accelerometer", - &flutter::StandardMethodCodec::GetInstance()); - auto accelerometer_channel_handler = - std::make_unique>( - [this](const flutter::EncodableValue *arguments, - std::unique_ptr> &&events) - -> std::unique_ptr> { - LOG_DEBUG("OnListen"); - accelerometer_listener_ = - std::make_unique(std::move(events)); - if (accelerometer_listener_->Init(SENSOR_ACCELEROMETER)) { - accelerometer_listener_->Listen(); - } - return nullptr; - }, - [this](const flutter::EncodableValue *arguments) - -> std::unique_ptr> { - LOG_DEBUG("OnCancel"); - if (accelerometer_listener_) { - accelerometer_listener_->Cancel(); - accelerometer_listener_ = nullptr; - } - return nullptr; - }); + accelerometer_channel_ = std::make_unique( + registrar->messenger(), + "dev.fluttercommunity.plus/sensors/accelerometer", + &flutter::StandardMethodCodec::GetInstance()); accelerometer_channel_->SetStreamHandler( - std::move(accelerometer_channel_handler)); - - gyroscope_channel_ = - std::make_unique>( - registrar->messenger(), - "dev.fluttercommunity.plus/sensors/gyroscope", - &flutter::StandardMethodCodec::GetInstance()); - auto gyroscope_channel_handler = - std::make_unique>( - [this](const flutter::EncodableValue *arguments, - std::unique_ptr> &&events) - -> std::unique_ptr> { - LOG_DEBUG("OnListen"); - gyroscope_listener_ = - std::make_unique(std::move(events)); - if (gyroscope_listener_->Init(SENSOR_GYROSCOPE)) { - gyroscope_listener_->Listen(); - } - return nullptr; - }, - [this](const flutter::EncodableValue *arguments) - -> std::unique_ptr> { - LOG_DEBUG("OnCancel"); - if (gyroscope_listener_) { - gyroscope_listener_->Cancel(); - gyroscope_listener_ = nullptr; - } - return nullptr; - }); - gyroscope_channel_->SetStreamHandler(std::move(gyroscope_channel_handler)); - - user_accel_channel_ = - std::make_unique>( - registrar->messenger(), - "dev.fluttercommunity.plus/sensors/user_accel", - &flutter::StandardMethodCodec::GetInstance()); - auto user_accel_handler = - std::make_unique>( - [this](const flutter::EncodableValue *arguments, - std::unique_ptr> &&events) - -> std::unique_ptr> { - LOG_DEBUG("OnListen"); - user_accel_listener_ = - std::make_unique(std::move(events)); - if (user_accel_listener_->Init(SENSOR_LINEAR_ACCELERATION)) { - user_accel_listener_->Listen(); - } - return nullptr; - }, - [this](const flutter::EncodableValue *arguments) - -> std::unique_ptr> { - LOG_DEBUG("OnCancel"); - if (user_accel_listener_) { - user_accel_listener_->Cancel(); - user_accel_listener_ = nullptr; - } - return nullptr; - }); - user_accel_channel_->SetStreamHandler(std::move(user_accel_handler)); + std::make_unique( + SensorType::kAccelerometer)); + + gyroscope_channel_ = std::make_unique( + registrar->messenger(), "dev.fluttercommunity.plus/sensors/gyroscope", + &flutter::StandardMethodCodec::GetInstance()); + gyroscope_channel_->SetStreamHandler( + std::make_unique(SensorType::kGyroscope)); + + user_accel_channel_ = std::make_unique( + registrar->messenger(), "dev.fluttercommunity.plus/sensors/user_accel", + &flutter::StandardMethodCodec::GetInstance()); + user_accel_channel_->SetStreamHandler( + std::make_unique(SensorType::kUserAccel)); } - std::unique_ptr> - accelerometer_channel_; - std::unique_ptr> - gyroscope_channel_; - std::unique_ptr> - user_accel_channel_; - std::unique_ptr accelerometer_listener_; - std::unique_ptr gyroscope_listener_; - std::unique_ptr user_accel_listener_; + std::unique_ptr accelerometer_channel_; + std::unique_ptr gyroscope_channel_; + std::unique_ptr user_accel_channel_; }; void SensorsPlusPluginRegisterWithRegistrar(