From 42244d9fb4d77ac3c55ae7d1f2f5ec62f01def69 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Thu, 7 Apr 2022 22:48:27 +0900 Subject: [PATCH] [connectivity_plus] Refactor the C++ code --- .../connectivity_plus/tizen/src/connection.cc | 74 ++++++ .../connectivity_plus/tizen/src/connection.h | 39 +++ .../src/connectivity_plus_tizen_plugin.cc | 224 ++++++++---------- 3 files changed, 208 insertions(+), 129 deletions(-) create mode 100644 packages/connectivity_plus/tizen/src/connection.cc create mode 100644 packages/connectivity_plus/tizen/src/connection.h diff --git a/packages/connectivity_plus/tizen/src/connection.cc b/packages/connectivity_plus/tizen/src/connection.cc new file mode 100644 index 000000000..6dae48029 --- /dev/null +++ b/packages/connectivity_plus/tizen/src/connection.cc @@ -0,0 +1,74 @@ +// 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 "connection.h" + +#include "log.h" + +static ConnectionType ToConnectionType(connection_type_e type) { + switch (type) { + case CONNECTION_TYPE_WIFI: + return ConnectionType::kWiFi; + case CONNECTION_TYPE_CELLULAR: + return ConnectionType::kMobile; + case CONNECTION_TYPE_ETHERNET: + return ConnectionType::kEthernet; + case CONNECTION_TYPE_DISCONNECTED: + default: + return ConnectionType::kNone; + } +} + +Connection::Connection() { + int ret = connection_create(&connection_); + if (ret != CONNECTION_ERROR_NONE) { + LOG_ERROR("Failed to create handle: %s", get_error_message(ret)); + last_error_ = ret; + } +} + +Connection::~Connection() { + if (connection_) { + connection_unset_type_changed_cb(connection_); + connection_destroy(connection_); + connection_ = nullptr; + } +} + +bool Connection::StartListen(ConnectionTypeCallback callback) { + int ret = connection_set_type_changed_cb( + connection_, + [](connection_type_e type, void *user_data) -> void { + auto *self = static_cast(user_data); + self->callback_(ToConnectionType(type)); + }, + this); + if (ret != CONNECTION_ERROR_NONE) { + LOG_ERROR("Failed to add callback: %s", get_error_message(ret)); + last_error_ = ret; + return false; + } + + callback_ = callback; + return true; +} + +void Connection::StopListen() { + int ret = connection_unset_type_changed_cb(connection_); + if (ret != CONNECTION_ERROR_NONE) { + LOG_ERROR("Failed to remove callback: %s", get_error_message(ret)); + last_error_ = ret; + } +} + +ConnectionType Connection::GetType() { + connection_type_e type; + int ret = connection_get_type(connection_, &type); + if (ret != CONNECTION_ERROR_NONE) { + LOG_ERROR("Failed to get connection type: %s", get_error_message(ret)); + last_error_ = ret; + return ConnectionType::kError; + } + return ToConnectionType(type); +} diff --git a/packages/connectivity_plus/tizen/src/connection.h b/packages/connectivity_plus/tizen/src/connection.h new file mode 100644 index 000000000..e5ffc6975 --- /dev/null +++ b/packages/connectivity_plus/tizen/src/connection.h @@ -0,0 +1,39 @@ +// 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_CONNECTION_H_ +#define FLUTTER_PLUGIN_CONNECTION_H_ + +#include +#include + +#include +#include + +enum class ConnectionType { kNone, kEthernet, kWiFi, kMobile, kError }; + +typedef std::function ConnectionTypeCallback; + +class Connection { + public: + Connection(); + ~Connection(); + + int GetLastError() { return last_error_; } + + std::string GetLastErrorString() { return get_error_message(last_error_); } + + bool StartListen(ConnectionTypeCallback callback); + + void StopListen(); + + ConnectionType GetType(); + + private: + int last_error_ = TIZEN_ERROR_NONE; + ConnectionTypeCallback callback_ = nullptr; + connection_h connection_; +}; + +#endif // FLUTTER_PLUGIN_CONNECTION_H_ diff --git a/packages/connectivity_plus/tizen/src/connectivity_plus_tizen_plugin.cc b/packages/connectivity_plus/tizen/src/connectivity_plus_tizen_plugin.cc index 71e8d728a..cbd6c5dd5 100644 --- a/packages/connectivity_plus/tizen/src/connectivity_plus_tizen_plugin.cc +++ b/packages/connectivity_plus/tizen/src/connectivity_plus_tizen_plugin.cc @@ -6,162 +6,128 @@ #include #include -#include +#include #include #include #include -#include -#include #include #include -#include "log.h" - -class ConnectivityPlusTizenPlugin : public flutter::Plugin { - public: - static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { - auto plugin = std::make_unique(); - plugin->SetupChannels(registrar); - registrar->AddPlugin(std::move(plugin)); - } - - ConnectivityPlusTizenPlugin() : connection_(nullptr), events_(nullptr) { - EnsureConnectionHandle(); +#include "connection.h" + +namespace { + +typedef flutter::EventChannel FlEventChannel; +typedef flutter::EventSink FlEventSink; +typedef flutter::MethodCall FlMethodCall; +typedef flutter::MethodResult FlMethodResult; +typedef flutter::MethodChannel FlMethodChannel; +typedef flutter::StreamHandler FlStreamHandler; +typedef flutter::StreamHandlerError + FlStreamHandlerError; + +std::string ConnectionTypeToString(ConnectionType type) { + switch (type) { + case ConnectionType::kEthernet: + return "ethernet"; + case ConnectionType::kWiFi: + return "wifi"; + case ConnectionType::kMobile: + return "mobile"; + case ConnectionType::kNone: + default: + return "none"; } +} - virtual ~ConnectivityPlusTizenPlugin() { - if (connection_ != nullptr) { - connection_destroy(connection_); - connection_ = nullptr; - } - } +class ConnectivityStreamHandler : public FlStreamHandler { + protected: + std::unique_ptr OnListenInternal( + const flutter::EncodableValue *arguments, + std::unique_ptr &&events) override { + events_ = std::move(events); - void RegisterObserver( - std::unique_ptr> &&events) { - EnsureConnectionHandle(); - if (connection_set_type_changed_cb( - connection_, - [](connection_type_e state, void *data) -> void { - auto *self = static_cast(data); - self->SendConnectivityChangedEvent(state); - }, - this) != CONNECTION_ERROR_NONE) { - return; + ConnectionTypeCallback callback = [this](ConnectionType type) -> void { + if (type != ConnectionType::kError) { + events_->Success(flutter::EncodableValue(ConnectionTypeToString(type))); + } else { + events_->Error(std::to_string(connection_.GetLastError()), + connection_.GetLastErrorString()); + } + }; + if (!connection_.StartListen(callback)) { + return std::make_unique( + std::to_string(connection_.GetLastError()), + connection_.GetLastErrorString(), nullptr); } - events_ = std::move(events); - } - void ClearObserver() { - if (connection_ == nullptr || events_ == nullptr) return; + // Send an initial event once the stream has been set up. + callback(connection_.GetType()); - connection_unset_type_changed_cb(connection_); - events_ = nullptr; + return nullptr; } - void SendConnectivityChangedEvent(connection_type_e state) { - if (events_ == nullptr) { - return; - } - std::string replay = ConvertConnectionTypeToString(state); - flutter::EncodableValue msg(replay); - events_->Success(msg); + std::unique_ptr OnCancelInternal( + const flutter::EncodableValue *arguments) override { + connection_.StopListen(); + events_.reset(); + return nullptr; } private: - void EnsureConnectionHandle() { - if (connection_ == nullptr) { - if (connection_create(&connection_) != CONNECTION_ERROR_NONE) { - connection_ = nullptr; - } - } - } + Connection connection_; + std::unique_ptr events_; +}; - std::string ConvertConnectionTypeToString(connection_type_e net_state) { - std::string result; - switch (net_state) { - case CONNECTION_TYPE_WIFI: - result = "wifi"; - break; - case CONNECTION_TYPE_ETHERNET: - result = "ethernet"; - break; - case CONNECTION_TYPE_CELLULAR: - result = "mobile"; - break; - case CONNECTION_TYPE_DISCONNECTED: - default: - result = "none"; - } - return result; +class ConnectivityPlusTizenPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { + auto plugin = std::make_unique(); + + auto method_channel = std::make_unique( + registrar->messenger(), "dev.fluttercommunity.plus/connectivity", + &flutter::StandardMethodCodec::GetInstance()); + method_channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + + auto event_channel = std::make_unique( + registrar->messenger(), "dev.fluttercommunity.plus/connectivity_status", + &flutter::StandardMethodCodec::GetInstance()); + event_channel->SetStreamHandler( + std::make_unique()); + + registrar->AddPlugin(std::move(plugin)); } - void HandleMethodCall( - const flutter::MethodCall &method_call, - std::unique_ptr> result) { - EnsureConnectionHandle(); - LOG_INFO("method : %s", method_call.method_name().data()); - - std::string replay = ""; - if (method_call.method_name().compare("check") == 0) { - connection_type_e net_state; - if (connection_get_type(connection_, &net_state) != - CONNECTION_ERROR_NONE) { - result->Error("-1", "Couldn't know current connection type"); - return; + ConnectivityPlusTizenPlugin() {} + + virtual ~ConnectivityPlusTizenPlugin() {} + + private: + void HandleMethodCall(const FlMethodCall &method_call, + std::unique_ptr result) { + const auto &method_name = method_call.method_name(); + + if (method_name == "check") { + Connection connection; + ConnectionType type = connection.GetType(); + if (type != ConnectionType::kError) { + result->Success(flutter::EncodableValue(ConnectionTypeToString(type))); + } else { + result->Error(std::to_string(connection.GetLastError()), + connection.GetLastErrorString()); } - replay = ConvertConnectionTypeToString(net_state); } else { - result->Error("-1", "Not supported method"); - return; + result->NotImplemented(); } - if (replay.length() == 0) { - result->Error("-1", "Not valid result"); - return; - } - - flutter::EncodableValue msg(replay); - result->Success(msg); } - - void SetupChannels(flutter::PluginRegistrar *registrar) { - auto method_channel = - std::make_unique>( - registrar->messenger(), "dev.fluttercommunity.plus/connectivity", - &flutter::StandardMethodCodec::GetInstance()); - event_channel_ = - std::make_unique>( - registrar->messenger(), - "dev.fluttercommunity.plus/connectivity_status", - &flutter::StandardMethodCodec::GetInstance()); - method_channel->SetMethodCallHandler([this](const auto &call, auto result) { - HandleMethodCall(call, std::move(result)); - }); - - auto event_channel_handler = - std::make_unique>( - [this](const flutter::EncodableValue *arguments, - std::unique_ptr> &&events) - -> std::unique_ptr> { - LOG_INFO("OnListen"); - RegisterObserver(std::move(events)); - return nullptr; - }, - [this](const flutter::EncodableValue *arguments) - -> std::unique_ptr> { - LOG_INFO("OnCancel"); - ClearObserver(); - return nullptr; - }); - event_channel_->SetStreamHandler(std::move(event_channel_handler)); - } - - std::unique_ptr> - event_channel_; - connection_h connection_; - std::unique_ptr> events_; }; +} // namespace + void ConnectivityPlusTizenPluginRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar) { ConnectivityPlusTizenPlugin::RegisterWithRegistrar(