diff --git a/packages/connectivity/.gitignore b/packages/connectivity/.gitignore new file mode 100644 index 000000000..e9dc58d3d --- /dev/null +++ b/packages/connectivity/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ diff --git a/packages/connectivity/CHANGELOG.md b/packages/connectivity/CHANGELOG.md new file mode 100644 index 000000000..4fee7f4a6 --- /dev/null +++ b/packages/connectivity/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +* Initial release \ No newline at end of file diff --git a/packages/connectivity/LICENSE b/packages/connectivity/LICENSE new file mode 100644 index 000000000..934dd180c --- /dev/null +++ b/packages/connectivity/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. +Copyright (c) 2017 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the names of the copyright holders nor the names of the + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/connectivity/README.md b/packages/connectivity/README.md new file mode 100644 index 000000000..b92ef0812 --- /dev/null +++ b/packages/connectivity/README.md @@ -0,0 +1,36 @@ +# connectivity_tizen + +The Tizen implementation of [`connectivity`](https://github.com/flutter/plugins/tree/master/packages/connectivity). + +## Usage + +This package is not an _endorsed_ implementation of `connectivity`. Therefore, you have to include `connectivity_tizen` alongside `connectivity` as dependencies in your `pubspec.yaml` file. + +```yaml +dependencies: + connectivity: ^2.0.2 + connectivity_tizen: ^1.0.0 +``` +Then you can import `connectivity` in your Dart code: + +```dart +import 'package:connectivity/connectivity.dart'; +``` + +For detailed usage, see https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity#usage. + +## Supported devices + +This plugin is supported on these types of devices: + +- Galaxy Watch (running Tizen 4.0 or later) + +## Required privileges + +To get connectivity information using this plugin, add below lines under the `` section in your `tizen-manifest.xml` file, + +```xml + + http://tizen.org/privilege/network.get + +``` diff --git a/packages/connectivity/example/.gitignore b/packages/connectivity/example/.gitignore new file mode 100644 index 000000000..9d532b18a --- /dev/null +++ b/packages/connectivity/example/.gitignore @@ -0,0 +1,41 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json diff --git a/packages/connectivity/example/README.md b/packages/connectivity/example/README.md new file mode 100644 index 000000000..885d1a356 --- /dev/null +++ b/packages/connectivity/example/README.md @@ -0,0 +1,7 @@ +# connectiviy example + +Demonstrates how to use the connectiviy plugin. + +## Getting Started + +To run this app on your Tizen device, use [flutter-tizen](https://github.com/flutter-tizen/flutter-tizen). diff --git a/packages/connectivity/example/integration_test/connectivity_test.dart b/packages/connectivity/example/integration_test/connectivity_test.dart new file mode 100644 index 000000000..d48deae34 --- /dev/null +++ b/packages/connectivity/example/integration_test/connectivity_test.dart @@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:integration_test/integration_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:connectivity/connectivity.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('Connectivity test driver', () { + Connectivity _connectivity; + + setUpAll(() async { + _connectivity = Connectivity(); + }); + + testWidgets('test connectivity result', (WidgetTester tester) async { + final ConnectivityResult result = await _connectivity.checkConnectivity(); + expect(result, isNotNull); + }); + }); +} diff --git a/packages/connectivity/example/lib/main.dart b/packages/connectivity/example/lib/main.dart new file mode 100644 index 000000000..e05497136 --- /dev/null +++ b/packages/connectivity/example/lib/main.dart @@ -0,0 +1,112 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs + +import 'dart:async'; +import 'dart:io'; + +import 'package:connectivity/connectivity.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +// Sets a platform override for desktop to avoid exceptions. See +// https://flutter.dev/desktop#target-platform-override for more info. +void _enablePlatformOverrideForDesktop() { + if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) { + debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; + } +} + +void main() { + _enablePlatformOverrideForDesktop(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, this.title}) : super(key: key); + + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + String _connectionStatus = 'Unknown'; + final Connectivity _connectivity = Connectivity(); + StreamSubscription _connectivitySubscription; + + @override + void initState() { + super.initState(); + initConnectivity(); + _connectivitySubscription = + _connectivity.onConnectivityChanged.listen(_updateConnectionStatus); + } + + @override + void dispose() { + _connectivitySubscription.cancel(); + super.dispose(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initConnectivity() async { + ConnectivityResult result; + // Platform messages may fail, so we use a try/catch PlatformException. + try { + result = await _connectivity.checkConnectivity(); + } on PlatformException catch (e) { + print(e.toString()); + } + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) { + return Future.value(null); + } + + return _updateConnectionStatus(result); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Connectivity example app'), + ), + body: Center(child: Text('Connection Status: $_connectionStatus')), + ); + } + + Future _updateConnectionStatus(ConnectivityResult result) async { + switch (result) { + case ConnectivityResult.wifi: + case ConnectivityResult.mobile: + case ConnectivityResult.none: + setState(() => _connectionStatus = result.toString()); + break; + default: + setState(() => _connectionStatus = 'Failed to get connectivity.'); + break; + } + } +} diff --git a/packages/connectivity/example/pubspec.yaml b/packages/connectivity/example/pubspec.yaml new file mode 100644 index 000000000..7c5f42dbc --- /dev/null +++ b/packages/connectivity/example/pubspec.yaml @@ -0,0 +1,22 @@ +name: connectivity_example +description: Demonstrates how to use the connectivity plugin. +publish_to: 'none' + +dependencies: + flutter: + sdk: flutter + connectivity: ^2.0.2 + connectivity_tizen: + path: ../ + +dev_dependencies: + flutter_driver: + sdk: flutter + test: any + pedantic: ^1.8.0 + integration_test: ^1.0.1 + integration_test_tizen: + path: ../../integration_test/ + +flutter: + uses-material-design: true diff --git a/packages/connectivity/example/test_driver/integration_test.dart b/packages/connectivity/example/test_driver/integration_test.dart new file mode 100644 index 000000000..b38629cca --- /dev/null +++ b/packages/connectivity/example/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/packages/connectivity/example/tizen/.gitignore b/packages/connectivity/example/tizen/.gitignore new file mode 100644 index 000000000..750f3af1b --- /dev/null +++ b/packages/connectivity/example/tizen/.gitignore @@ -0,0 +1,5 @@ +flutter/ +.vs/ +*.user +bin/ +obj/ diff --git a/packages/connectivity/example/tizen/App.cs b/packages/connectivity/example/tizen/App.cs new file mode 100644 index 000000000..6dd4a6356 --- /dev/null +++ b/packages/connectivity/example/tizen/App.cs @@ -0,0 +1,20 @@ +using Tizen.Flutter.Embedding; + +namespace Runner +{ + public class App : FlutterApplication + { + protected override void OnCreate() + { + base.OnCreate(); + + GeneratedPluginRegistrant.RegisterPlugins(this); + } + + static void Main(string[] args) + { + var app = new App(); + app.Run(args); + } + } +} diff --git a/packages/connectivity/example/tizen/NuGet.Config b/packages/connectivity/example/tizen/NuGet.Config new file mode 100644 index 000000000..c4ea70c17 --- /dev/null +++ b/packages/connectivity/example/tizen/NuGet.Config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/connectivity/example/tizen/Runner.csproj b/packages/connectivity/example/tizen/Runner.csproj new file mode 100644 index 000000000..497f928b8 --- /dev/null +++ b/packages/connectivity/example/tizen/Runner.csproj @@ -0,0 +1,26 @@ + + + + Exe + tizen40 + + + + portable + + + none + + + + + + + + + + %(RecursiveDir) + + + + diff --git a/packages/connectivity/example/tizen/shared/res/ic_launcher.png b/packages/connectivity/example/tizen/shared/res/ic_launcher.png new file mode 100644 index 000000000..4d6372eeb Binary files /dev/null and b/packages/connectivity/example/tizen/shared/res/ic_launcher.png differ diff --git a/packages/connectivity/example/tizen/tizen-manifest.xml b/packages/connectivity/example/tizen/tizen-manifest.xml new file mode 100644 index 000000000..79b020a01 --- /dev/null +++ b/packages/connectivity/example/tizen/tizen-manifest.xml @@ -0,0 +1,14 @@ + + + + + + ic_launcher.png + + + + + + http://tizen.org/privilege/network.get + + diff --git a/packages/connectivity/pubspec.yaml b/packages/connectivity/pubspec.yaml new file mode 100644 index 000000000..627f578c9 --- /dev/null +++ b/packages/connectivity/pubspec.yaml @@ -0,0 +1,28 @@ +name: connectivity_tizen +description: Flutter plugin for discovering the state of the network (WiFi) connectivity on Tizen. +version: 1.0.0 +homepage: https://github.com/flutter-tizen/plugins + +flutter: + plugin: + platforms: + tizen: + pluginClass: ConnectivityTizenPlugin + fileName: connectivity_tizen_plugin.h +dependencies: + connectivity: ^2.0.2 + connectivity_platform_interface: ^1.0.6 + flutter: + sdk: flutter + +dev_dependencies: + test: any + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + mockito: ^4.1.1 + +environment: + sdk: ">=2.6.0 <3.0.0" + flutter: ">=1.12.13+hotfix.4" diff --git a/packages/connectivity/tizen/.gitignore b/packages/connectivity/tizen/.gitignore new file mode 100644 index 000000000..a2a7d62b1 --- /dev/null +++ b/packages/connectivity/tizen/.gitignore @@ -0,0 +1,5 @@ +.cproject +.sign +crash-info/ +Debug/ +Release/ diff --git a/packages/connectivity/tizen/inc/connectivity_tizen_plugin.h b/packages/connectivity/tizen/inc/connectivity_tizen_plugin.h new file mode 100644 index 000000000..1ab386046 --- /dev/null +++ b/packages/connectivity/tizen/inc/connectivity_tizen_plugin.h @@ -0,0 +1,23 @@ +#ifndef FLUTTER_PLUGIN_CONNECTIVITY_TIZEN_PLUGIN_H_ +#define FLUTTER_PLUGIN_CONNECTIVITY_TIZEN_PLUGIN_H_ + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) +#else +#define FLUTTER_PLUGIN_EXPORT +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void ConnectivityTizenPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_PLUGIN_CONNECTIVITY_TIZEN_PLUGIN_H_ diff --git a/packages/connectivity/tizen/project_def.prop b/packages/connectivity/tizen/project_def.prop new file mode 100644 index 000000000..c753e7328 --- /dev/null +++ b/packages/connectivity/tizen/project_def.prop @@ -0,0 +1,30 @@ +# See https://docs.tizen.org/application/tizen-studio/native-tools/project-conversion +# for details. + +APPNAME = connectivity_tizen_plugin +type = sharedLib +profile = common-4.0 + +# Source files +USER_SRCS += src/connectivity_tizen_plugin.cc + +# User defines +USER_DEFS = +USER_UNDEFS = +USER_CPP_DEFS = TIZEN_DEPRECATION DEPRECATION_WARNING FLUTTER_PLUGIN_IMPL +USER_CPP_UNDEFS = + +# Compiler/linker flags +USER_CFLAGS_MISC = +USER_CPPFLAGS_MISC = -c -fmessage-length=0 +USER_LFLAGS = + +# Libraries and objects +USER_LIB_DIRS = lib +USER_LIBS = +USER_OBJS = + +# User includes +USER_INC_DIRS = inc src +USER_INC_FILES = +USER_CPP_INC_FILES = diff --git a/packages/connectivity/tizen/src/connectivity_tizen_plugin.cc b/packages/connectivity/tizen/src/connectivity_tizen_plugin.cc new file mode 100644 index 000000000..0eb771d19 --- /dev/null +++ b/packages/connectivity/tizen/src/connectivity_tizen_plugin.cc @@ -0,0 +1,164 @@ +// Copyright 2020 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 "connectivity_tizen_plugin.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "log.h" + +class ConnectivityTizenPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { + LOG_INFO("RegisterWithRegistrar"); + auto method_channel = + std::make_unique>( + registrar->messenger(), "plugins.flutter.io/connectivity", + &flutter::StandardMethodCodec::GetInstance()); + auto event_channel = + std::make_unique>( + registrar->messenger(), "plugins.flutter.io/connectivity_status", + &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(); + method_channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + auto event_channel_handler = + std::make_unique>( + [plugin_pointer = plugin.get()]( + const flutter::EncodableValue *arguments, + std::unique_ptr> &&events) + -> std::unique_ptr> { + LOG_INFO("OnListen"); + plugin_pointer->registerObsever(std::move(events)); + return nullptr; + }, + [plugin_pointer = + plugin.get()](const flutter::EncodableValue *arguments) + -> std::unique_ptr> { + LOG_INFO("OnCancel"); + plugin_pointer->clearObserver(); + return nullptr; + }); + event_channel->SetStreamHandler(std::move(event_channel_handler)); + registrar->AddPlugin(std::move(plugin)); + } + + ConnectivityTizenPlugin() : m_connection(nullptr), m_events(nullptr) { + ensureConnectionHandle(); + } + + virtual ~ConnectivityTizenPlugin() { + if (m_connection != nullptr) { + connection_destroy(m_connection); + m_connection = nullptr; + } + } + + void registerObsever( + std::unique_ptr> &&events) { + ensureConnectionHandle(); + if (connection_set_type_changed_cb(m_connection, connetionTypeChangedCB, + this) != CONNECTION_ERROR_NONE) { + return; + } + m_events = std::move(events); + } + + void clearObserver() { + if (m_connection == nullptr || m_events == nullptr) return; + + connection_unset_type_changed_cb(m_connection); + m_events = nullptr; + } + + void sendConnectivityChangedEvent(connection_type_e state) { + if (m_events == nullptr) return; + std::string replay = convertConnectionTypeToString(state); + flutter::EncodableValue msg(replay); + m_events->Success(&msg); + } + + private: + static void connetionTypeChangedCB(connection_type_e state, void *data) { + LOG_DEBUG("connetionTypeChangedCB"); + ConnectivityTizenPlugin *plugin_pointer = (ConnectivityTizenPlugin *)data; + plugin_pointer->sendConnectivityChangedEvent(state); + } + + void ensureConnectionHandle() { + if (m_connection == nullptr) { + if (connection_create(&m_connection) != CONNECTION_ERROR_NONE) { + m_connection = nullptr; + } + } + } + + std::string convertConnectionTypeToString(connection_type_e net_state) { + std::string result; + switch (net_state) { + case CONNECTION_TYPE_WIFI: + case CONNECTION_TYPE_ETHERNET: + result = "wifi"; + break; + case CONNECTION_TYPE_CELLULAR: + result = "mobile"; + break; + case CONNECTION_TYPE_DISCONNECTED: + default: + result = "none"; + } + return result; + } + + 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(m_connection, &net_state) != + CONNECTION_ERROR_NONE) { + result->Error("-1", "Couldn't know current connection type"); + return; + } + replay = convertConnectionTypeToString(net_state); + } else { + result->Error("-1", "Not supported method"); + return; + } + if (replay.length() == 0) { + result->Error("-1", "Not valid result"); + return; + } + + flutter::EncodableValue msg(replay); + result->Success(&msg); + } + connection_h m_connection; + std::unique_ptr> m_events; +}; + +void ConnectivityTizenPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + ConnectivityTizenPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +} diff --git a/packages/connectivity/tizen/src/log.h b/packages/connectivity/tizen/src/log.h new file mode 100644 index 000000000..e415b0f4a --- /dev/null +++ b/packages/connectivity/tizen/src/log.h @@ -0,0 +1,20 @@ +#ifndef __LOG_H__ +#define __LOG_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "ConnectivityTizenPlugin" + +#define LOG(prio, fmt, arg...) \ + dlog_print(prio, LOG_TAG, "%s: %s(%d) > " fmt, __FILE__, __func__, __LINE__, \ + ##arg) + +#define LOG_DEBUG(fmt, args...) LOG(DLOG_DEBUG, fmt, ##args) +#define LOG_INFO(fmt, args...) LOG(DLOG_INFO, fmt, ##args) +#define LOG_WARN(fmt, args...) LOG(DLOG_WARN, fmt, ##args) +#define LOG_ERROR(fmt, args...) LOG(DLOG_ERROR, fmt, ##args) + +#endif // __LOG_H__