From b09c1243c901c4f9385f679521dc708cb9f1fdd7 Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Thu, 17 Feb 2022 13:42:41 -0600 Subject: [PATCH] feat(windows): create my_plugin_windows (#5) --- .github/workflows/my_plugin_windows.yaml | 21 ++++++ src/my_plugin_windows/.gitignore | 29 ++++++++ src/my_plugin_windows/.metadata | 10 +++ src/my_plugin_windows/CHANGELOG.md | 3 + src/my_plugin_windows/LICENSE | 21 ++++++ src/my_plugin_windows/README.md | 14 ++++ src/my_plugin_windows/analysis_options.yaml | 1 + .../lib/my_plugin_windows.dart | 20 ++++++ src/my_plugin_windows/pubspec.yaml | 27 +++++++ .../test/my_plugin_windows_test.dart | 44 ++++++++++++ src/my_plugin_windows/windows/.gitignore | 17 +++++ src/my_plugin_windows/windows/CMakeLists.txt | 22 ++++++ .../my_plugin_windows/my_plugin_windows.h | 23 ++++++ .../windows/my_plugin_windows_plugin.cpp | 72 +++++++++++++++++++ 14 files changed, 324 insertions(+) create mode 100644 .github/workflows/my_plugin_windows.yaml create mode 100644 src/my_plugin_windows/.gitignore create mode 100644 src/my_plugin_windows/.metadata create mode 100644 src/my_plugin_windows/CHANGELOG.md create mode 100644 src/my_plugin_windows/LICENSE create mode 100644 src/my_plugin_windows/README.md create mode 100644 src/my_plugin_windows/analysis_options.yaml create mode 100644 src/my_plugin_windows/lib/my_plugin_windows.dart create mode 100644 src/my_plugin_windows/pubspec.yaml create mode 100644 src/my_plugin_windows/test/my_plugin_windows_test.dart create mode 100644 src/my_plugin_windows/windows/.gitignore create mode 100644 src/my_plugin_windows/windows/CMakeLists.txt create mode 100644 src/my_plugin_windows/windows/include/my_plugin_windows/my_plugin_windows.h create mode 100644 src/my_plugin_windows/windows/my_plugin_windows_plugin.cpp diff --git a/.github/workflows/my_plugin_windows.yaml b/.github/workflows/my_plugin_windows.yaml new file mode 100644 index 0000000..613850a --- /dev/null +++ b/.github/workflows/my_plugin_windows.yaml @@ -0,0 +1,21 @@ +name: my_plugin_windows + +on: + pull_request: + paths: + - ".github/workflows/my_plugin_windows.yaml" + - "src/my_plugin_windows/**" + push: + branches: + - main + paths: + - ".github/workflows/my_plugin_windows.yaml" + - "src/my_plugin_windows/**" + +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_windows diff --git a/src/my_plugin_windows/.gitignore b/src/my_plugin_windows/.gitignore new file mode 100644 index 0000000..9be145f --- /dev/null +++ b/src/my_plugin_windows/.gitignore @@ -0,0 +1,29 @@ +# 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 +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/src/my_plugin_windows/.metadata b/src/my_plugin_windows/.metadata new file mode 100644 index 0000000..8c15ad7 --- /dev/null +++ b/src/my_plugin_windows/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 77d935af4db863f6abd0b9c31c7e6df2a13de57b + channel: stable + +project_type: plugin diff --git a/src/my_plugin_windows/CHANGELOG.md b/src/my_plugin_windows/CHANGELOG.md new file mode 100644 index 0000000..1455983 --- /dev/null +++ b/src/my_plugin_windows/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_windows/LICENSE b/src/my_plugin_windows/LICENSE new file mode 100644 index 0000000..bba8e50 --- /dev/null +++ b/src/my_plugin_windows/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_windows/README.md b/src/my_plugin_windows/README.md new file mode 100644 index 0000000..b40523a --- /dev/null +++ b/src/my_plugin_windows/README.md @@ -0,0 +1,14 @@ +# my_plugin_windows + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] + +The windows 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_windows/analysis_options.yaml b/src/my_plugin_windows/analysis_options.yaml new file mode 100644 index 0000000..44aef9a --- /dev/null +++ b/src/my_plugin_windows/analysis_options.yaml @@ -0,0 +1 @@ +include: package:very_good_analysis/analysis_options.2.4.0.yaml diff --git a/src/my_plugin_windows/lib/my_plugin_windows.dart b/src/my_plugin_windows/lib/my_plugin_windows.dart new file mode 100644 index 0000000..c854a63 --- /dev/null +++ b/src/my_plugin_windows/lib/my_plugin_windows.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 Windows implementation of [MyPluginPlatform]. +class MyPluginWindows extends MyPluginPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('my_plugin_windows'); + + /// Registers this class as the default instance of [MyPluginPlatform] + static void registerWith() { + MyPluginPlatform.instance = MyPluginWindows(); + } + + @override + Future getPlatformName() { + return methodChannel.invokeMethod('getPlatformName'); + } +} diff --git a/src/my_plugin_windows/pubspec.yaml b/src/my_plugin_windows/pubspec.yaml new file mode 100644 index 0000000..531d6bc --- /dev/null +++ b/src/my_plugin_windows/pubspec.yaml @@ -0,0 +1,27 @@ +name: my_plugin_windows +description: Windows 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: + windows: + pluginClass: MyPluginWindows + dartPluginClass: MyPluginWindows + +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_windows/test/my_plugin_windows_test.dart b/src/my_plugin_windows/test/my_plugin_windows_test.dart new file mode 100644 index 0000000..d09b05e --- /dev/null +++ b/src/my_plugin_windows/test/my_plugin_windows_test.dart @@ -0,0 +1,44 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:my_plugin_platform_interface/my_plugin_platform_interface.dart'; +import 'package:my_plugin_windows/my_plugin_windows.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('MyPluginWindows', () { + const kPlatformName = 'Windows'; + late MyPluginWindows myPlugin; + late List log; + + setUp(() async { + myPlugin = MyPluginWindows(); + + 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', () { + MyPluginWindows.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)); + }); + }); +} diff --git a/src/my_plugin_windows/windows/.gitignore b/src/my_plugin_windows/windows/.gitignore new file mode 100644 index 0000000..b3eb2be --- /dev/null +++ b/src/my_plugin_windows/windows/.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_windows/windows/CMakeLists.txt b/src/my_plugin_windows/windows/CMakeLists.txt new file mode 100644 index 0000000..47cb775 --- /dev/null +++ b/src/my_plugin_windows/windows/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.14) +set(PROJECT_NAME "my_plugin_windows") +project(${PROJECT_NAME} LANGUAGES CXX) + +set(PLUGIN_NAME "${PROJECT_NAME}_plugin") + +add_library(${PLUGIN_NAME} SHARED + "my_plugin_windows_plugin.cpp" + "include/my_plugin_windows/my_plugin_windows.h" +) +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 flutter_wrapper_plugin) + +# List of absolute paths to libraries that should be bundled with the plugin +set(my_plugin_bundled_libraries + "" + PARENT_SCOPE +) \ No newline at end of file diff --git a/src/my_plugin_windows/windows/include/my_plugin_windows/my_plugin_windows.h b/src/my_plugin_windows/windows/include/my_plugin_windows/my_plugin_windows.h new file mode 100644 index 0000000..6d08a1f --- /dev/null +++ b/src/my_plugin_windows/windows/include/my_plugin_windows/my_plugin_windows.h @@ -0,0 +1,23 @@ +#ifndef FLUTTER_PLUGIN_MY_PLUGIN_WINDOWS_PLUGIN_H_ +#define FLUTTER_PLUGIN_MY_PLUGIN_WINDOWS_PLUGIN_H_ + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) +#else +#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void MyPluginWindowsRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_PLUGIN_MY_PLUGIN_WINDOWS_PLUGIN_H_ diff --git a/src/my_plugin_windows/windows/my_plugin_windows_plugin.cpp b/src/my_plugin_windows/windows/my_plugin_windows_plugin.cpp new file mode 100644 index 0000000..d861f12 --- /dev/null +++ b/src/my_plugin_windows/windows/my_plugin_windows_plugin.cpp @@ -0,0 +1,72 @@ +#include "include/my_plugin_windows/my_plugin_windows.h" + +// This must be included before many other Windows headers. +#include + +#include +#include +#include + +#include +#include + +namespace { + +using flutter::EncodableValue; + +class MyPluginWindows : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar); + + MyPluginWindows(); + + virtual ~MyPluginWindows(); + + private: + // Called when a method is called on this plugin's channel from Dart. + void HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result); +}; + +// static +void MyPluginWindows::RegisterWithRegistrar( + flutter::PluginRegistrarWindows *registrar) { + auto channel = + std::make_unique>( + registrar->messenger(), "my_plugin_windows", + &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(); + + channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto &call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + + registrar->AddPlugin(std::move(plugin)); +} + +MyPluginWindows::MyPluginWindows() {} + +MyPluginWindows::~MyPluginWindows() {} + +void MyPluginWindows::HandleMethodCall( + const flutter::MethodCall &method_call, + std::unique_ptr> result) { + if (method_call.method_name().compare("getPlatformName") == 0) { + result->Success(EncodableValue("Windows")); + } + else { + result->NotImplemented(); + } +} + +} // namespace + +void MyPluginWindowsRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + MyPluginWindows::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +}