diff --git a/.github/workflows/my_plugin_linux.yaml b/.github/workflows/my_plugin_linux.yaml new file mode 100644 index 0000000..a45b354 --- /dev/null +++ b/.github/workflows/my_plugin_linux.yaml @@ -0,0 +1,21 @@ +name: my_plugin_linux + +on: + pull_request: + paths: + - ".github/workflows/my_plugin_linux.yaml" + - "src/my_plugin_linux/**" + push: + branches: + - main + paths: + - ".github/workflows/my_plugin_linux.yaml" + - "src/my_plugin_linux/**" + +jobs: + build: + uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1 + with: + flutter_channel: stable + flutter_version: 2.10.1 + working_directory: src/my_plugin_linux diff --git a/src/my_plugin_linux/.gitignore b/src/my_plugin_linux/.gitignore new file mode 100644 index 0000000..e9dc58d --- /dev/null +++ b/src/my_plugin_linux/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ diff --git a/src/my_plugin_linux/CHANGELOG.md b/src/my_plugin_linux/CHANGELOG.md new file mode 100644 index 0000000..1455983 --- /dev/null +++ b/src/my_plugin_linux/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.1.0+1 + +- Initial release of this plugin. \ No newline at end of file diff --git a/src/my_plugin_linux/LICENSE b/src/my_plugin_linux/LICENSE new file mode 100644 index 0000000..bba8e50 --- /dev/null +++ b/src/my_plugin_linux/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Very Good Ventures + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/my_plugin_linux/README.md b/src/my_plugin_linux/README.md new file mode 100644 index 0000000..68a97f9 --- /dev/null +++ b/src/my_plugin_linux/README.md @@ -0,0 +1,14 @@ +# my_plugin_linux + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] + +The linux implementation of `my_plugin`. + +## Usage + +This package is [endorsed][endorsed_link], which means you can simply use `my_plugin` +normally. This package will be automatically included in your app when you do. + +[endorsed_link]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis diff --git a/src/my_plugin_linux/analysis_options.yaml b/src/my_plugin_linux/analysis_options.yaml new file mode 100644 index 0000000..44aef9a --- /dev/null +++ b/src/my_plugin_linux/analysis_options.yaml @@ -0,0 +1 @@ +include: package:very_good_analysis/analysis_options.2.4.0.yaml diff --git a/src/my_plugin_linux/lib/my_plugin_linux.dart b/src/my_plugin_linux/lib/my_plugin_linux.dart new file mode 100644 index 0000000..b8998f6 --- /dev/null +++ b/src/my_plugin_linux/lib/my_plugin_linux.dart @@ -0,0 +1 @@ +export 'src/my_plugin_linux.dart'; diff --git a/src/my_plugin_linux/lib/src/my_plugin_linux.dart b/src/my_plugin_linux/lib/src/my_plugin_linux.dart new file mode 100644 index 0000000..3cb6e66 --- /dev/null +++ b/src/my_plugin_linux/lib/src/my_plugin_linux.dart @@ -0,0 +1,20 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:my_plugin_platform_interface/my_plugin_platform_interface.dart'; + +/// The Linux implementation of [MyPluginPlatform]. +class MyPluginLinux extends MyPluginPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('my_plugin_linux'); + + /// Registers this class as the default instance of [MyPluginPlatform] + static void registerWith() { + MyPluginPlatform.instance = MyPluginLinux(); + } + + @override + Future getPlatformName() { + return methodChannel.invokeMethod('getPlatformName'); + } +} diff --git a/src/my_plugin_linux/linux/.gitignore b/src/my_plugin_linux/linux/.gitignore new file mode 100644 index 0000000..b3eb2be --- /dev/null +++ b/src/my_plugin_linux/linux/.gitignore @@ -0,0 +1,17 @@ +flutter/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/src/my_plugin_linux/linux/CMakeLists.txt b/src/my_plugin_linux/linux/CMakeLists.txt new file mode 100644 index 0000000..f8a4125 --- /dev/null +++ b/src/my_plugin_linux/linux/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.10) +set(PROJECT_NAME "my_plugin_linux") +project(${PROJECT_NAME} LANGUAGES CXX) + +set(PLUGIN_NAME "${PROJECT_NAME}_plugin") + +list(APPEND PLUGIN_SOURCES + "my_plugin_linux_plugin.cc" +) + +add_library(${PLUGIN_NAME} SHARED + ${PLUGIN_SOURCES} +) +apply_standard_settings(${PLUGIN_NAME}) +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter) +target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK) diff --git a/src/my_plugin_linux/linux/include/my_plugin_linux/my_plugin_plugin.h b/src/my_plugin_linux/linux/include/my_plugin_linux/my_plugin_plugin.h new file mode 100644 index 0000000..cc12c30 --- /dev/null +++ b/src/my_plugin_linux/linux/include/my_plugin_linux/my_plugin_plugin.h @@ -0,0 +1,25 @@ +#ifndef FLUTTER_PLUGIN_MY_PLUGIN_LINUX_PLUGIN_H_ +#define FLUTTER_PLUGIN_MY_PLUGIN_LINUX_PLUGIN_H_ + +#include + +G_BEGIN_DECLS + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) +#else +#define FLUTTER_PLUGIN_EXPORT +#endif + +G_DECLARE_FINAL_TYPE(FlMyPluginPlugin, fl_my_plugin_plugin, FL, + MY_PLUGIN_PLUGIN, GObject) + +FLUTTER_PLUGIN_EXPORT FlMyPluginPlugin* fl_my_plugin_plugin_new( + FlPluginRegistrar* registrar); + +FLUTTER_PLUGIN_EXPORT void my_plugin_plugin_register_with_registrar( + FlPluginRegistrar* registrar); + +G_END_DECLS + +#endif // FLUTTER_PLUGIN_MY_PLUGIN_LINUX_PLUGIN_H_ \ No newline at end of file diff --git a/src/my_plugin_linux/linux/my_plugin_linux_plugin.cc b/src/my_plugin_linux/linux/my_plugin_linux_plugin.cc new file mode 100644 index 0000000..0f015ac --- /dev/null +++ b/src/my_plugin_linux/linux/my_plugin_linux_plugin.cc @@ -0,0 +1,68 @@ +#include "include/my_plugin_linux/my_plugin_plugin.h" + +#include +#include +#include + +#include + +const char kChannelName[] = "my_plugin_linux"; +const char kGetPlatformName[] = "getPlatformName"; + +struct _FlMyPluginPlugin { + GObject parent_instance; + + FlPluginRegistrar* registrar; + + // Connection to Flutter engine. + FlMethodChannel* channel; +}; + +G_DEFINE_TYPE(FlMyPluginPlugin, fl_my_plugin_plugin, g_object_get_type()) + +// Called when a method call is received from Flutter. +static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call, + gpointer user_data) { + const gchar* method = fl_method_call_get_name(method_call); + + g_autoptr(FlMethodResponse) response = nullptr; + if (strcmp(method, kGetPlatformName) == 0) + response = FL_METHOD_RESPONSE(fl_method_success_response_new(fl_value_new_string("Linux"))); + else + response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); + + g_autoptr(GError) error = nullptr; + if (!fl_method_call_respond(method_call, response, &error)) + g_warning("Failed to send method call response: %s", error->message); +} + +static void fl_my_plugin_plugin_dispose(GObject* object) { + G_OBJECT_CLASS(fl_my_plugin_plugin_parent_class)->dispose(object); +} + +static void fl_my_plugin_plugin_class_init(FlMyPluginPluginClass* klass) { + G_OBJECT_CLASS(klass)->dispose = fl_my_plugin_plugin_dispose; +} + +FlMyPluginPlugin* fl_my_plugin_plugin_new(FlPluginRegistrar* registrar) { + FlMyPluginPlugin* self = FL_MY_PLUGIN_PLUGIN( + g_object_new(fl_my_plugin_plugin_get_type(), nullptr)); + + self->registrar = FL_PLUGIN_REGISTRAR(g_object_ref(registrar)); + + g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new(); + self->channel = + fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar), + kChannelName, FL_METHOD_CODEC(codec)); + fl_method_channel_set_method_call_handler(self->channel, method_call_cb, + g_object_ref(self), g_object_unref); + + return self; +} + +static void fl_my_plugin_plugin_init(FlMyPluginPlugin* self) {} + +void my_plugin_plugin_register_with_registrar(FlPluginRegistrar* registrar) { + FlMyPluginPlugin* plugin = fl_my_plugin_plugin_new(registrar); + g_object_unref(plugin); +} diff --git a/src/my_plugin_linux/pubspec.yaml b/src/my_plugin_linux/pubspec.yaml new file mode 100644 index 0000000..73d0e3f --- /dev/null +++ b/src/my_plugin_linux/pubspec.yaml @@ -0,0 +1,27 @@ +name: my_plugin_linux +description: Linux implementation of the my_plugin plugin +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ">=2.12.0 <3.0.0" + flutter: ">=2.0.0" + +flutter: + plugin: + implements: my_plugin + platforms: + linux: + pluginClass: MyPluginPlugin + dartPluginClass: MyPluginLinux + +dependencies: + flutter: + sdk: flutter + my_plugin_platform_interface: + path: ../my_plugin_platform_interface + +dev_dependencies: + flutter_test: + sdk: flutter + very_good_analysis: ^2.4.0 diff --git a/src/my_plugin_linux/test/my_plugin_linux_test.dart b/src/my_plugin_linux/test/my_plugin_linux_test.dart new file mode 100644 index 0000000..e308621 --- /dev/null +++ b/src/my_plugin_linux/test/my_plugin_linux_test.dart @@ -0,0 +1,44 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:my_plugin_linux/my_plugin_linux.dart'; +import 'package:my_plugin_platform_interface/my_plugin_platform_interface.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('MyPluginLinux', () { + const kPlatformName = 'Linux'; + late MyPluginLinux myPlugin; + late List log; + + setUp(() async { + myPlugin = MyPluginLinux(); + + log = []; + TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger + .setMockMethodCallHandler(myPlugin.methodChannel, (methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'getPlatformName': + return kPlatformName; + default: + return null; + } + }); + }); + + test('can be registered', () { + MyPluginLinux.registerWith(); + expect(MyPluginPlatform.instance, isA()); + }); + + test('getPlatformName returns correct name', () async { + final name = await myPlugin.getPlatformName(); + expect( + log, + [isMethodCall('getPlatformName', arguments: null)], + ); + expect(name, equals(kPlatformName)); + }); + }); +}