diff --git a/README.md b/README.md
index e246fa9..cfe77b3 100644
--- a/README.md
+++ b/README.md
@@ -1,60 +1,35 @@
-
-
-
-
# Плагины для ОС Аврора
-Этот репозиторий содержит Flutter плагины для платформы ОС Аврора. Мы находимся в процессе создания необходимых плагинов для разработки всевозможных приложений пользователей.
-
-Если плагин который вы ищете еще не реализован для ОС Аврора оставьте свое сообщение в [issue](https://gitlab.com/omprussia/flutter/flutter-plugins/-/issues), либо рассмотрите возможность самостоятельной разработки плагина для развития Open Source сообщества ОС Аврора. Мы будем рады вашим мерж-реквестам!
-
-# Разработка плагина для ОС Аврора
-
-Подробно процесс создания платформозависимых плагинов описан в статье [«Flutter на ОС Аврора»](#todo).
-
-Если у вас имеются вопросы, присоединяйтесь к [сообществу](https://t.me/aurora_devs) ОС Аврора в Telegram канале, где вы сможете задать интересующий вас вопрос и следить за всеми актульными новостями.
-
-Для разработки платформозависимого плагина, необходимо использовать адаптированный под ОС Аврора [Flutter SDK](https://gitlab.com/omprussia/flutter/flutter).
-
-Ниже перечислены четыре вида плагинов, которые могут
-применяться в ОС Аврора.
-
-- ### Dart Package
-
- Пакет написанный на языке Dart, например пакет [`path`](https://pub.dev/packages/path), расширяющий возможности Flutter, добавляя в него новые виджеты или функции, который не является платформозависимым.
-
-- ### Plugin Package
-
- Пакет, предоставляющий API на языке Dart в сочетании с одной или несколькими реализациями под конкретные платформы, использующий механизм [Platform Channels](https://docs.flutter.dev/platform-integration/platform-channels).
- Для реализации плагина под ОС Аврора используется язык C++.
+![preview.png](documentation/data/preview.png)
-- ### Qt Plugin Package
+Этот репозиторий содержит плагины Flutter для платформы ОС Аврора. Мы находимся в процессе создания необходимых плагинов для разработки всевозможных приложений пользователей. Если плагин который вы ищете еще не реализован для ОС Аврора оставьте сообщение в [issue](https://gitlab.com/omprussia/flutter/flutter-plugins/-/issues) либо рассмотрите возможность создать пакет самостоятельно. Мы будем рады вашим мерж-реквестам!
- Пакет, аналогичный `Plugin Package`, но использующий в реализации под ОС Аврора библиотеку Qt. Данный вид пакета используется в случае, если системное API ОС Аврора, предоставляющее необходимую функциональность, использует библиотеку Qt.
+## Разработка плагина для ОС Аврора
- ОС Аврора старается минимизировать использование библиотеки Qt в Flutter плагинах, поэтому, если имеется возможность не использовать библиотеку Qt в реализации плагина под ОС Аврора, то лучше ее не использовать.
+Что бы создать платформо-зависимый плагин воспользуйтесь [Flutter SDK](https://gitlab.com/omprussia/flutter/flutter) с поддержкой ОС Аврора. Для платформы Аврора доступно четыре варианта создания плагина, все они перечислены ниже с примерами:
-- ### FFI Plugin Package
+- [Dart package](documentation/dart_package.md);
+- [Plugin package](documentation/plugin_package.md);
+- [Qt plugin package](documentation/qt_plugin_package.md);
+- [FFI Plugin package](documentation/ffi_plugin_package.md).
- Пакет, предоставляющий API на языке Dart в сочетании с одной или несколькими реализациями под конкретные платформы, использующий механизм [Dart FFI](https://dart.dev/guides/libraries/c-interop).
+Подробно процесс создания платформо-зависимых плагинов можно найти в статье "[Flutter на ОС Аврора](https://habr.com/ru/articles/761176/)". Если остаются вопросы присоединяйтесь к сообществу ОС Аврора "[Aurora Developers](https://t.me/aurora_devs)" в Telegram, там вы сможете задать вопрос по Flutter и следить за новостями.
-# Демонстрационное приложение
+## Демонстрационное приложение
-Плагины из данного проекта объеденены в одно [общее приложение](./example), предназначеное для демонстрации работы реализованных и проверенных на ОС Аврора плагинов.
+![preview.png](documentation/data/preview_app.png)
-
-
-
+Все плагины имеют общее демонстрационное приложение **Flutter example packages**. Оно предназначено для демонстрации работы как платформо-зависимых так и нет плагинов/пакетов. Выполняет роль единого приложения-примера для платформо-зависимых плагинов и позволяет проверить работоспособность не платформо зависимых плагинов на платформе ОС Аврора.
-# Платформозависимые плагины Flutter
+## Платформо-зависимые плагины Flutter
-Список платформозависимых плагинов, реализованых под ОС Аврора, либо зависящих от платформозависимых плагинов.
+Список платформо-зависимых плагинов созданных для ОС Аврора либо зависящих от платформо-зависимых плагинов ОС Аврора.
| Плагин ОС Аврора | Версия | Внешний плагин | Версия | Версия ОС Аврора |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------------------------------------------------------------------------|----------|--------------------|
| [battery_plus_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/battery_plus/battery_plus_aurora) | `0.0.1` | [battery_plus](https://pub.dev/packages/battery_plus) | `4.0.1` | `4.0.2.269` |
| [device_info_plus_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/device_info_plus/device_info_plus_aurora) | `0.0.1` | [device_info_plus](https://pub.dev/packages/device_info_plus) | `8.2.2` | `4.0.2.269` |
-| [flutter_keyboard_visibility_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/flutter_keyboard_visibility/flutter_keyboard_visibility_aurora) | `0.0.1` | [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) | `5.4.1` | `4.0.2.269` |
+| [flutter_keyboard_visibility_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/flutter_keyboard_visibility/flutter_keyboard_visibility_aurora) | `0.0.1` | [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) | `5.4.1` | `4.0.2.269` |
| [flutter_local_notifications_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/flutter_local_notifications/flutter_local_notifications_aurora) | `0.0.1` | [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications) | `14.1.1` | `4.0.2.269` |
| [flutter_secure_storage_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/flutter_secure_storage/flutter_secure_storage_aurora) | `0.0.1` | [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) | `8.0.0` | `4.0.2.269` |
| [package_info_plus_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/package_info_plus/package_info_plus_aurora) | `0.0.1` | [package_info_plus](https://pub.dev/packages/package_info_plus) | `3.1.2` | `4.0.2.269` |
@@ -63,40 +38,35 @@
| [sqflite_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/sqflite/sqflite_aurora) | `0.0.1` | [sqflite](https://pub.dev/packages/sqflite) | `2.2.6` | `4.0.2.269` |
| [wakelock_aurora](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/wakelock/wakelock_aurora) | `0.0.1` | [wakelock](https://pub.dev/packages/wakelock) | `0.6.2` | `4.0.2.269` |
| [xdga_directories](https://gitlab.com/omprussia/flutter/flutter-plugins/-/tree/master/packages/xdga_directories) | `0.0.1` | - | - | `4.0.2.269` |
-| - | - | [flutter_cache_manager](https://pub.dev/packages/flutter_cache_manager) | `3.3.0` | `4.0.2.269` |
-| - | - | [cached_network_image](https://pub.dev/packages/cached_network_image) | `3.2.3` | `4.0.2.269` |
-| - | - | [google_fonts](https://pub.dev/packages/google_fonts) | `4.0.4` | `4.0.2.269` |
-
-# Пакеты Flutter
-
-Список проверенных на совместимость c ОС Аврора пакетов, не являющихся платформозависимыми.
-
-| Внешний плагин | Версия | Версия ОС Аврора |
-|-------------------------------------------------------------------------------------|----------|--------------------|
-| [crypto](https://pub.dev/packages/crypto) | `3.0.2` | `4.0.2.269` |
-| [cupertino_icons](https://pub.dev/packages/cupertino_icons) | `1.0.5` | `4.0.2.269` |
-| [get_it](https://pub.dev/packages/get_it) | `7.6.0` | `4.0.2.269` |
-| [intl](https://pub.dev/packages/intl) | `0.17.0` | `4.0.2.269` |
-| [photo_view](https://pub.dev/packages/photo_view) | `0.14.0` | `4.0.2.269` |
-| [scoped_model](https://pub.dev/packages/scoped_model) | `2.0.0` | `4.0.2.269` |
-| [dartz](https://pub.dev/packages/dartz) | `0.10.1` | `4.0.2.269` |
-| [freezed](https://pub.dev/packages/freezed) | `2.3.3` | `4.0.2.269` |
-| [equatable](https://pub.dev/packages/equatable) | `2.0.5` | `4.0.2.269` |
-| [flutter_markdown](https://pub.dev/packages/flutter_markdown) | `0.6.15` | `4.0.2.269` |
-| [build_runner](https://pub.dev/packages/build_runner) | `2.3.3` | `4.0.2.269` |
-| [freezed_annotation](https://pub.dev/packages/freezed_annotation) | `2.2.0` | `4.0.2.269` |
-| [json_annotation](https://pub.dev/packages/json_annotation) | `4.8.0` | `4.0.2.269` |
-| [json_serializable](https://pub.dev/packages/json_serializable) | `6.6.1` | `4.0.2.269` |
-| [provider](https://pub.dev/packages/provider) | `6.0.5` | `4.0.2.269` |
-| [qr_flutter](https://pub.dev/packages/qr_flutter) | `4.0.0` | `4.0.2.269` |
-| [rxdart](https://pub.dev/packages/rxdart) | `0.27.7` | `4.0.2.269` |
-| [translator](https://pub.dev/packages/translator) | `0.1.7` | `4.0.2.269` |
-
-# Вклад сообщества
-
-Этот проект поддерживается сообществом. Оставляйте ваши вопросы и отзывы в [issues](https://gitlab.com/omprussia/flutter/flutter-plugins/-/issues) проекта,
-либо публикуйте ваши наработки в репозиторий через [merge request](https://gitlab.com/omprussia/flutter/flutter-plugins/-/merge_requests).
-
-Помните, что [демонстрационное приложение](./example) содержит не только сложные платформозависимые плагины, но и обычные пакеты, поэтому мы будем рады, если вы проверите ваши любимые Flutter пакеты на работоспособность в ОС Аврора и поделитесь вашими наработками с сообществом.
-
-Мы будем рады любому вашему вкладу в развитие проекта.
+| - | - | [flutter_cache_manager](https://pub.dev/packages/flutter_cache_manager) | 3.3.0 | `4.0.2.269` |
+| - | - | [cached_network_image](https://pub.dev/packages/cached_network_image) | 3.2.3 | `4.0.2.269` |
+| - | - | [google_fonts](https://pub.dev/packages/google_fonts) | 4.0.4 | `4.0.2.269` |
+
+## Пакеты Flutter
+
+Список проверенных на совместимость и работоспособность в ОС Аврора пакетов Flutter не являющиеся платформо-зависимыми.
+
+| Внешний плагин | Версия | Версия ОС Аврора |
+|-------------------------------------------------------------------------------------|---------|--------------------|
+| [crypto](https://pub.dev/packages/crypto) | 3.0.2 | `4.0.2.269` |
+| [cupertino_icons](https://pub.dev/packages/cupertino_icons) | 1.0.5 | `4.0.2.269` |
+| [get_it](https://pub.dev/packages/get_it) | 7.6.0 | `4.0.2.269` |
+| [intl](https://pub.dev/packages/intl) | 0.17.0 | `4.0.2.269` |
+| [photo_view](https://pub.dev/packages/photo_view) | 0.14.0 | `4.0.2.269` |
+| [scoped_model](https://pub.dev/packages/scoped_model) | 2.0.0 | `4.0.2.269` |
+| [dartz](https://pub.dev/packages/dartz) | 0.10.1 | `4.0.2.269` |
+| [freezed](https://pub.dev/packages/freezed) | 2.3.3 | `4.0.2.269` |
+| [equatable](https://pub.dev/packages/equatable) | 2.0.5 | `4.0.2.269` |
+| [flutter_markdown](https://pub.dev/packages/flutter_markdown) | 0.6.15 | `4.0.2.269` |
+| [build_runner](https://pub.dev/packages/build_runner) | 2.3.3 | `4.0.2.269` |
+| [freezed_annotation](https://pub.dev/packages/freezed_annotation) | 2.2.0 | `4.0.2.269` |
+| [json_annotation](https://pub.dev/packages/json_annotation) | 4.8.0 | `4.0.2.269` |
+| [json_serializable](https://pub.dev/packages/json_serializable) | 6.6.1 | `4.0.2.269` |
+| [provider](https://pub.dev/packages/provider) | 6.0.5 | `4.0.2.269` |
+| [qr_flutter](https://pub.dev/packages/qr_flutter) | 4.0.0 | `4.0.2.269` |
+| [rxdart](https://pub.dev/packages/rxdart) | 0.27.7 | `4.0.2.269` |
+| [translator](https://pub.dev/packages/translator) | 0.1.7 | `4.0.2.269` |
+
+## Вклад
+
+Этот проект поддерживается сообществом, и мы будем рады вашему вкладу и активности, оставляйте ваши вопросы, отзывы в [issue](https://gitlab.com/omprussia/flutter/flutter-plugins/-/issues) либо вашу работу в [мерж-реквесты](https://gitlab.com/omprussia/flutter/flutter-plugins/-/merge_requests). Помните что **Flutter example packages** содержит не только сложные платформо-зависимые плагины, мы будем рады вкладу в проверку на работоспособность платформо не зависимых плагинов.
diff --git a/data/preview.png b/data/preview.png
deleted file mode 100644
index 4a63ba8..0000000
Binary files a/data/preview.png and /dev/null differ
diff --git a/data/preview_app.png b/data/preview_app.png
deleted file mode 100644
index b0e4405..0000000
Binary files a/data/preview_app.png and /dev/null differ
diff --git a/documentation/dart_package.md b/documentation/dart_package.md
new file mode 100644
index 0000000..e9c7472
--- /dev/null
+++ b/documentation/dart_package.md
@@ -0,0 +1,119 @@
+# Dart package
+
+Пакеты написанные на Dart, например package [`path`](https://pub.dev/packages/path). Они могут содержать специфичные для Flutter функции и иметь зависимость от инфраструктуры Flutter, ограничивая их использование только Flutter, например package [`fluro`](https://pub.dev/packages/fluro).
+
+> Для демонстрации создания платформо-зависимого пакета для ОС Аврора типа "Dart package" был написан и опубликован проект "[Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages)" которые подробно описан в статье "[Flutter на ОС Аврора](https://habr.com/ru/articles/761176/)".
+
+Проект "[Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages)" содержит в себе пакет реализующий платформо-зависимый пакет для ОС Аврора типа "Dart package". Вообще этот тип пакета может быть как платформо-зависимым так и нет. Пакет "[Flutter Device](https://gitlab.com/omprussia/flutter/demo-dart-packages/-/tree/master/packages/aurora/dart_package_device?ref_type=heads)" из проекта [Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages) становится платформо-зависимым использую [D-Bus](https://www.freedesktop.org/wiki/Software/dbus/) ОС Аврора. Данный пакет использует API ОС Аврора - "[Device Info API](https://developer.auroraos.ru/doc/software_development/reference/device_info)".
+
+Пакет Dart в минимальном виде состоит из файла [`pubspec.yaml`](https://dart.dev/tools/pub/pubspec), папки `lib` с как минимум одним файлом `.dart`. Создать пакет можно командой:
+
+```shell
+$ flutter-aurora create --template=package
+```
+
+Рассмотрим пакет "[dart_package_device](https://gitlab.com/omprussia/flutter/demo-dart-packages/-/tree/master/packages/aurora/dart_package_device?ref_type=heads)" из проекта [Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages). **dart_package_device** - платформо-зависимая реализация плагина "Flutter Device" для ОС Аврора типа "Dart package". В основе пакета лежит пакет `dbus` - нативная клиентская реализация D-Bus для Dart. С его помощью можно реализовать пакет Dart для ОС Аврора, ни строчки не написав на C++.
+
+Структура пакета **dart_package_device**:
+
+```shell
+└── aurora
+ └── dart_package_device
+ ├── lib
+ │ ├── dart_package_device.dart
+ │ └── ru_omp_device_info_features.dart
+ ├── ru.omp.deviceinfo.Features.xml
+ └── pubspec.yaml
+```
+
+Пакет `dbus` позволяет на основе xml-файла с интерфейсом D-Bus генерировать Dart-класс, который позволит выполнить доступные методы.
+
+Файл `packages/aurora/dart_package_device/ru.omp.deviceinfo.Features.xml`
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+Выполнить генерацию можно командой:
+
+```shell
+$ dart-dbus generate-remote-object ./ru.omp.deviceinfo.Features.xml \
+-o lib/ru_omp_device_info_features.dart
+```
+
+Результат генерации c файла `ru.omp.deviceinfo.Features.xml` следует рассматривать, как отправную точку для реализации.
+
+Файл `packages/aurora/dart_package_device/lib/ru_omp_device_info_features.dart`
+
+```dart
+class RuOmpDeviceinfoFeatures extends DBusRemoteObject {
+ RuOmpDeviceinfoFeatures(
+ DBusClient client, String destination, DBusObjectPath path)
+ : super(client, name: destination, path: path);
+
+ /// Вызов ru.omp.deviceinfo.Features.getDeviceModel()
+ Future callGetDeviceModel(
+ {bool noAutoStart = false,
+ bool allowInteractiveAuthorization = false}) async {
+ var result = await callMethod(
+ 'ru.omp.deviceinfo.Features', 'getDeviceModel', [],
+ replySignature: DBusSignature('s'),
+ noAutoStart: noAutoStart,
+ allowInteractiveAuthorization: allowInteractiveAuthorization);
+ return result.returnValues[0].asString();
+ }
+}
+```
+
+Теперь можно реализовать интерфейс **[device_platform_interface](https://gitlab.com/omprussia/flutter/demo-dart-packages/-/tree/master/device_platform_interface?ref_type=heads)** и в методе `registerWith` указать пакет **dart_package_device**, как платформо-зависимый плагин.
+
+Файл `packages/aurora/dart_package_device/lib/dart_package_device.dart`
+
+```dart
+/// Метод, который выполнится при старте приложения
+/// В этом методе можно установить платформо-зависимый плагин
+static void registerWith() {
+ DevicePlatform.instance = DartPackageDevice();
+}
+
+/// Реализация метода интерфейса [DevicePlatform]
+@override
+Future get deviceName async {
+ // Инициализация клиента D-Bus
+ final client = DBusClient.session();
+
+ // Инициализация объекта
+ final features = RuOmpDeviceinfoFeatures(
+ client,
+ 'ru.omp.deviceinfo',
+ DBusObjectPath('/ru/omp/deviceinfo/Features'),
+ );
+
+ // Выполнение метода
+ final deviceName = await features.callGetDeviceModel();
+
+ // Закрытие клиента D-Bus
+ await client.close();
+
+ // Возвращение результата
+ return deviceName == '' ? null : deviceName;
+}
+```
+
+В `pubspec.yaml` плагина **dart_package_device** следует указать `dartPluginClass` для того, чтобы с помощью метода `registerWith` прошла регистрация плагина в `общем-плагине` **flutter_device** при старте приложения.
+
+```yaml
+flutter:
+ plugin:
+ platforms:
+ aurora:
+ dartPluginClass: DartPackageDevice
+```
\ No newline at end of file
diff --git a/documentation/data/preview.png b/documentation/data/preview.png
new file mode 100644
index 0000000..04e20a1
Binary files /dev/null and b/documentation/data/preview.png differ
diff --git a/documentation/data/preview_app.png b/documentation/data/preview_app.png
new file mode 100644
index 0000000..79d1794
Binary files /dev/null and b/documentation/data/preview_app.png differ
diff --git a/documentation/ffi_plugin_package.md b/documentation/ffi_plugin_package.md
new file mode 100644
index 0000000..64e33dc
--- /dev/null
+++ b/documentation/ffi_plugin_package.md
@@ -0,0 +1,185 @@
+# FFI Plugin package
+
+Специализированный пакет Dart, содержащий API, написанный на Dart, с одной или несколькими реализациями для конкретной платформы, использующими [Dart FFI](https://dart.dev/guides/libraries/c-interop).
+
+> Для демонстрации создания платформо-зависимого плагина для ОС Аврора типа "FFI Plugin package" был написан и опубликован проект "[Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages)" которые подробно описан в статье "[Flutter на ОС Аврора](https://habr.com/ru/articles/761176/)".
+
+Проект "[Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages)" содержит в себе пакет реализующий платформо-зависимый плагин для ОС Аврора типа "FFI Plugin package". Данный пакет использует API ОС Аврора - "[Device Info API](https://developer.auroraos.ru/doc/software_development/reference/device_info)". Плагин использует [QtDBus](https://doc.qt.io/qt-5/qtdbus-index.html) но не является типом плагина "Qt plugin package" так как не использует сигналы и слоты.
+
+Создать пакет "FFI Plugin package" можно командой:
+
+```shell
+$ flutter-aurora create --template=plugin_ffi
+```
+
+Рассмотрим плагин "[ffi_plugin_device](https://gitlab.com/omprussia/flutter/demo-dart-packages/-/tree/master/packages/aurora/ffi_plugin_device?ref_type=heads)" из проекта [Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages). **ffi_plugin_device** - платформо-зависимая реализация плагина "Flutter Device" для ОС Аврора типа "FFI Plugin package".
+
+Структура пакета **ffi_plugin_device**
+
+```shell
+└── aurora
+ └── ffi_plugin_device
+ ├── aurora
+ │ └── CMakeLists.txt
+ ├── ffigen.yaml
+ ├── lib
+ │ ├── ffi_plugin_device_bindings_generated.dart
+ │ └── ffi_plugin_device.dart
+ ├── pubspec.yaml
+ └── src
+ ├── CMakeLists.txt
+ ├── ffi_plugin_device.cpp
+ └── ffi_plugin_device.h
+```
+
+Для генерации привязок FFI можно использовать плагин [`ffigen`](https://pub.dev/packages/ffigen). Пакет, предоставляющий утилиты для работы с кодом интерфейса внешних функций, называется [`ffi`](https://pub.dev/packages/ffi). В `pubspec.yaml` плагина нужно добавить зависимости и активировать `ffiPlugin` для платформы ОС Аврора.
+
+```yaml
+dependencies:
+ ffi: ^2.0.2
+
+dev_dependencies:
+ ffigen: ^7.2.7
+
+flutter:
+ plugin:
+ platforms:
+ aurora:
+ ffiPlugin: true
+ dartPluginClass: FFIPluginDevice
+```
+
+Для генерации привязок нужно добавить файл `ffigen.yaml` в корень плагина.
+
+Файл `packages/aurora/ffi_plugin_device/ffigen.yaml`
+
+```yaml
+name: PluginDeviceBindings
+llvm-path:
+ - '/usr/lib/llvm-14/lib/libclang.so' # Ubuntu 22.04
+ - '/usr/lib/llvm-15/lib/libclang.so' # Ubuntu 23.04
+description: |
+ Bindings for `src/ffi_plugin_device.h`.
+output: 'lib/ffi_plugin_device_bindings_generated.dart'
+headers:
+ entry-points:
+ - 'src/ffi_plugin_device.h'
+ include-directives:
+ - 'src/ffi_plugin_device.h'
+comments:
+ style: any
+ length: full
+```
+
+В файле `ffigen.yaml` указываются хедеры нужных библиотек. В данном случае библиотека лежит в папке `src`, которая получает название модели устройства с помощью [`Qt D-Bus`](https://doc.qt.io/qt-5/qtdbus-index.html).
+
+Файл `packages/aurora/ffi_plugin_device/src/ffi_plugin_device.h`
+
+```cpp
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *getDeviceName();
+
+#ifdef __cplusplus
+}
+#endif
+```
+
+Файл `packages/aurora/ffi_plugin_device/src/ffi_plugin_device.cpp`
+
+```cpp
+#include
+#include
+
+#include "ffi_plugin_device.h"
+
+char *getDeviceName()
+{
+ QString deviceName = "";
+ if (QDBusConnection::sessionBus().isConnected()) {
+ QDBusInterface iface("ru.omp.deviceinfo",
+ "/ru/omp/deviceinfo/Features",
+ "",
+ QDBusConnection::sessionBus()
+ );
+ if (iface.isValid()) {
+ QDBusReply reply = iface.call("getDeviceModel");
+ if (reply.isValid()) {
+ deviceName = reply.value();
+ }
+ }
+ }
+ return deviceName.toUtf8().data();
+}
+```
+
+Выполнить генерацию FFI-привязок можно следующей командой, выполнив её из корня плагина (например, `packages/aurora/ffi_plugin_device`):
+
+```shell
+flutter-aurora pub run ffigen --config ffigen.yaml
+```
+
+В папке `lib` будет сгенерирован файл `ffi_plugin_device_bindings_generated.dart`.
+
+Файл `packages/aurora/ffi_plugin_device/lib/ffi_plugin_device_bindings_generated.dart`
+
+```dart
+import 'dart:ffi' as ffi;
+
+/// Bindings for `src/ffi_plugin_device.h`.
+class PluginDeviceBindings {
+ /// Holds the symbol lookup function.
+ final ffi.Pointer Function(String symbolName)
+ _lookup;
+
+ /// The symbols are looked up in [dynamicLibrary].
+ PluginDeviceBindings(ffi.DynamicLibrary dynamicLibrary)
+ : _lookup = dynamicLibrary.lookup;
+
+ /// The symbols are looked up with [lookup].
+ PluginDeviceBindings.fromLookup(
+ ffi.Pointer Function(String symbolName)
+ lookup)
+ : _lookup = lookup;
+
+ ffi.Pointer getDeviceName() {
+ return _getDeviceName();
+ }
+
+ late final _getDeviceNamePtr =
+ _lookup Function()>>(
+ 'getDeviceName');
+ late final _getDeviceName =
+ _getDeviceNamePtr.asFunction Function()>();
+}
+```
+
+Теперь можно создать класс `FFIPluginDevice`, реализующий интерфейс **[device_platform_interface](https://gitlab.com/omprussia/flutter/demo-dart-packages/-/tree/master/device_platform_interface?ref_type=heads)**.
+
+Файл `packages/aurora/ffi_plugin_device/lib/ffi_plugin_device.dart`
+
+```dart
+class FFIPluginDevice extends DevicePlatform {
+ /// Метод, который выполнится при старте приложения
+ /// В этом методе можно установить платформо-зависимый плагин
+ static void registerWith() {
+ DevicePlatform.instance = FFIPluginDevice();
+ }
+
+ /// Привязки к нативным функциям в [_dylib].
+ final PluginDeviceBindings _bindings = PluginDeviceBindings(
+ DynamicLibrary.open('libffi_plugin_device.so'),
+ );
+
+ /// Реализация метода интерфейса [DevicePlatform]
+ @override
+ Future get deviceName async {
+ // Получение deviceName
+ final deviceName = _bindings.getDeviceName().cast().toDartString();
+ // Возврат результата
+ return deviceName == '' ? null : deviceName;
+ }
+}
+```
\ No newline at end of file
diff --git a/documentation/plugin_package.md b/documentation/plugin_package.md
new file mode 100644
index 0000000..60316c2
--- /dev/null
+++ b/documentation/plugin_package.md
@@ -0,0 +1,166 @@
+# Plugin package
+
+Специализированный пакет Dart, содержащий API, написанный на Dart, в сочетании с одной или несколькими реализациями для конкретной платформы. Пакеты плагинов могут быть написаны для Android (с использованием Kotlin или Java), ОС Аврора (с использование С++), iOS (с использованием Swift или Objective-C), Интернета, macOS, Windows или Linux или любой их комбинации.
+
+> Для демонстрации создания платформо-зависимого пакета для ОС Аврора типа "Plugin package" был написан и опубликован проект "[Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages)" которые подробно описан в статье "[Flutter на ОС Аврора](https://habr.com/ru/articles/761176/)".
+
+Проект "[Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages)" содержит в себе пакет реализующий платформо-зависимый плагин для ОС Аврора типа "Plugin package". Данный пакет использует API ОС Аврора - "[Device Info API](https://developer.auroraos.ru/doc/software_development/reference/device_info)". Плагин использует [QtDBus](https://doc.qt.io/qt-5/qtdbus-index.html) но не является типом плагина "Qt plugin package" так как не использует сигналы и слоты.
+
+Создать пакет "Plugin package" можно командой:
+
+```shell
+$ flutter-aurora create --template=plugin
+```
+
+Рассмотрим плагин "[plugin_device](https://gitlab.com/omprussia/flutter/demo-dart-packages/-/tree/master/packages/aurora/plugin_device?ref_type=heads)" из проекта [Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages). **plugin_device** - платформо-зависимая реализация плагина "Flutter Device" для ОС Аврора типа "Plugin package".
+
+Структура пакета **plugin_device**:
+
+```shell
+└── aurora
+ └── plugin_device
+ ├── aurora
+ │ ├── CMakeLists.txt
+ │ ├── include
+ │ │ └── plugin_device
+ │ │ └── plugin_device_plugin.h
+ │ └── plugin_device_plugin.cpp
+ ├── lib
+ │ ├── plugin_device.dart
+ │ └── plugin_device_method_channel.dart
+ └── pubspec.yaml
+```
+
+В `pubspec.yaml` плагина **plugin_device** нужно указать `pluginClass` и `dartPluginClass`.
+
+```yaml
+flutter:
+ plugin:
+ platforms:
+ aurora:
+ pluginClass: PluginDevicePlugin
+ dartPluginClass: PluginDevice
+```
+
+`PluginDevicePlugin` - C++ класс реализующий `PluginInterface` пакета `flutter-embedder`.
+
+Файл `packages/aurora/plugin_device/aurora/include/plugin_device/plugin_device_plugin.h`
+
+```cpp
+#include
+#include
+
+class PLUGIN_EXPORT PluginDevicePlugin final : public PluginInterface
+{
+public:
+ void RegisterWithRegistrar(PluginRegistrar ®istrar) override;
+
+private:
+ void onMethodCall(const MethodCall &call);
+ void onGetDeviceName(const MethodCall &call);
+ void unimplemented(const MethodCall &call);
+};
+```
+
+Файл `packages/aurora/plugin_device/aurora/plugin_device_plugin.cpp`
+
+```cpp
+#include
+#include
+#include
+
+/**
+ * Регистрация [MethodChannel].
+ */
+void PluginDevicePlugin::RegisterWithRegistrar(PluginRegistrar ®istrar)
+{
+ registrar.RegisterMethodChannel("plugin_device",
+ MethodCodecType::Standard,
+ [this](const MethodCall &call) { this->onMethodCall(call); });
+}
+
+/**
+ * Метод onMethodCall будет выполняться при вызове MethodChannel из Dart-плагина.
+ * По названию, передаваемому из плагина, можно вызвать нужный платформо-зависимый метод.
+ */
+void PluginDevicePlugin::onMethodCall(const MethodCall &call)
+{
+ const auto &method = call.GetMethod();
+ if (method == "getDeviceName") {
+ onGetDeviceName(call);
+ return;
+ }
+ unimplemented(call);
+}
+
+/**
+ * Платформо-зависимый метод, получающий название устройства
+ */
+void PluginDevicePlugin::onGetDeviceName(const MethodCall &call)
+{
+ if (!QDBusConnection::sessionBus().isConnected()) {
+ call.SendSuccessResponse(nullptr);
+ return;
+ }
+ QDBusInterface iface("ru.omp.deviceinfo",
+ "/ru/omp/deviceinfo/Features",
+ "",
+ QDBusConnection::sessionBus()
+ );
+ if (iface.isValid()) {
+ QDBusReply reply = iface.call("getDeviceModel");
+ if (reply.isValid()) {
+ call.SendSuccessResponse(reply.value().toStdString());
+ return;
+ }
+ }
+ call.SendSuccessResponse(nullptr);
+}
+
+/**
+ * Метод возвращающий [nullptr], если запрашиваемый метод не найден
+ */
+void PluginDevicePlugin::unimplemented(const MethodCall &call)
+{
+ call.SendSuccessResponse(nullptr);
+}
+```
+
+`PluginDevice` - Dart-класс, реализующий **[device_platform_interface](https://gitlab.com/omprussia/flutter/demo-dart-packages/-/tree/master/device_platform_interface?ref_type=heads)** и устанавливающий при выполнении метода `registerWith` нужный экземпляр для взаимодействия с платформо-зависимой частью плагина.
+
+Файл `packages/aurora/plugin_device/lib/plugin_device.dart`
+
+```dart
+class PluginDevice extends DevicePlatform {
+ /// Метод, который выполнится при старте приложения
+ /// В этом методе можно установить платформо-зависимый плагин
+ static void registerWith() {
+ DevicePlatform.instance = MethodChannelPluginDevice();
+ }
+
+ /// Реализация метода интерфейса [DevicePlatform]
+ @override
+ Future get deviceName => DevicePlatform.instance.deviceName;
+}
+```
+
+[MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) класс плагина отличается от подобного класса для Android только названием и ключом для взаимодействия с платформо-зависимой частью.
+
+Файл `packages/aurora/plugin_device/lib/plugin_device_method_channel.dart`
+
+```dart
+/// Реализация [PluginDevicePlatform], которая использует каналы методов
+class MethodChannelPluginDevice extends DevicePlatform {
+ /// Канал метода, используемый для взаимодействия с собственной платформой
+ @visibleForTesting
+ final methodChannel = const MethodChannel('plugin_device');
+
+ /// Реализация метода получения названия устройства
+ /// getDeviceName - название метода, который можно проверить
+ /// в платформо-зависимой части плагина
+ @override
+ Future get deviceName async {
+ return await methodChannel.invokeMethod('getDeviceName');
+ }
+}
+```
\ No newline at end of file
diff --git a/documentation/qt_plugin_package.md b/documentation/qt_plugin_package.md
new file mode 100644
index 0000000..4c853c9
--- /dev/null
+++ b/documentation/qt_plugin_package.md
@@ -0,0 +1,123 @@
+# Qt plugin package
+
+Qt plugin package - является обычным плагином типа "[Plugin package](#todo)", но использующего Qt сигналы и слоты. Проект "[Demo Dart Packages](https://gitlab.com/omprussia/flutter/demo-dart-packages)" содержит в себе пакет реализующий платформо-зависимый плагин для ОС Аврора типа "Plugin package", на его примере покажем как подключить сигналы и слоты к плагину.
+
+Плагин уже имеет в зависимостях Qt, но в нем не будут работать сигналы и слоты. Для их подключения следует добавить зависимости в класс реализующий `PluginInterface`:
+
+Файл `packages/aurora/plugin_device/aurora/include/plugin_device/plugin_device_plugin.h`
+
+```cpp
+#include
+#include
+
+#include
+
+class PLUGIN_EXPORT PluginDevicePlugin final
+ : public QObject,
+ public PluginInterface
+{
+ Q_OBJECT
+
+public:
+ void RegisterWithRegistrar(PluginRegistrar ®istrar) override;
+
+private:
+ void onMethodCall(const MethodCall &call);
+ void onGetDeviceName(const MethodCall &call);
+ void unimplemented(const MethodCall &call);
+};
+```
+
+А в файл реализации добавить в низ файла `#include "moc_sensors_plus_aurora_plugin.cpp"`:
+
+Файл `packages/aurora/plugin_device/aurora/plugin_device_plugin.cpp`
+
+```cpp
+#include
+#include
+#include
+
+/**
+ * Регистрация [MethodChannel].
+ */
+void PluginDevicePlugin::RegisterWithRegistrar(PluginRegistrar ®istrar)
+{
+ registrar.RegisterMethodChannel("plugin_device",
+ MethodCodecType::Standard,
+ [this](const MethodCall &call) { this->onMethodCall(call); });
+}
+
+/**
+ * Метод onMethodCall будет выполняться при вызове MethodChannel из Dart-плагина.
+ * По названию, передаваемому из плагина, можно вызвать нужный платформо-зависимый метод.
+ */
+void PluginDevicePlugin::onMethodCall(const MethodCall &call)
+{
+ const auto &method = call.GetMethod();
+ if (method == "getDeviceName") {
+ onGetDeviceName(call);
+ return;
+ }
+ unimplemented(call);
+}
+
+/**
+ * Платформо-зависимый метод, получающий название устройства
+ */
+void PluginDevicePlugin::onGetDeviceName(const MethodCall &call)
+{
+ if (!QDBusConnection::sessionBus().isConnected()) {
+ call.SendSuccessResponse(nullptr);
+ return;
+ }
+ QDBusInterface iface("ru.omp.deviceinfo",
+ "/ru/omp/deviceinfo/Features",
+ "",
+ QDBusConnection::sessionBus()
+ );
+ if (iface.isValid()) {
+ QDBusReply reply = iface.call("getDeviceModel");
+ if (reply.isValid()) {
+ call.SendSuccessResponse(reply.value().toStdString());
+ return;
+ }
+ }
+ call.SendSuccessResponse(nullptr);
+}
+
+/**
+ * Метод возвращающий [nullptr], если запрашиваемый метод не найден
+ */
+void PluginDevicePlugin::unimplemented(const MethodCall &call)
+{
+ call.SendSuccessResponse(nullptr);
+}
+
+#include "moc_sensors_plus_aurora_plugin.cpp"
+```
+
+И для того что бы мок файл сгенерировался добавим в [set_target_properties](https://cmake.org/cmake/help/latest/command/set_target_properties.html) `AUTOMOC ON`:
+
+Файл `packages/aurora/plugin_device/aurora/CMakeLists.txt`
+
+```
+set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden AUTOMOC ON)
+```
+
+Для работы плагина в приложении Qt нужно включить отдельно. Сделать это можно добавив в `main` функцию приложения вызов метода `EnableQtCompatibility()`. Выглядеть это может следующим образом:
+
+```cpp
+#include
+#include
+#include "generated_plugin_registrant.h"
+
+int main(int argc, char *argv[]) {
+ Application::Initialize(argc, argv);
+ EnableQtCompatibility(); // Включение "Qt plugin package" плагинов
+ RegisterPlugins();
+ Application::Launch();
+ return 0;
+}
+```
+
+Добавив зависимости в плагин начнут работать сигналы и слоты Qt. ОС Аврора очень зависит от Qt, во Flutter мы стараемся минимизировать эту зависимость. Если есть возможность выбора типа для реализации платформо-зависимого плагина использование Qt нежелательно.
\ No newline at end of file
diff --git a/example/app_run.sh b/example/app_run.sh
new file mode 100755
index 0000000..8f8a72b
--- /dev/null
+++ b/example/app_run.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+# Copyright (c) 2023. Open Mobile Platform LLC.
+# License: Proprietary.
+
+## Build example, sign rpm, upload/install/run rpm to device
+
+## Usage
+##
+## chmod +x ./run.sh
+##
+## ./run.sh \
+## -d : \
+## -s /home/user/sign/folder
+## -p ru.auroraos.flutter_example_packages
+
+sudo echo 'Run...';
+
+## Flutter path
+FLUTTER="$HOME/.local/opt/flutter/bin/flutter"
+
+## https://developer.auroraos.ru/doc/software_development/psdk/setup
+## Install Platform SDK path
+## You may not have set the PSDK_DIR environment variable.
+## export PSDK_DIR=$HOME/AuroraPlatformSDK/sdks/aurora_psdk
+
+while getopts d:s:p: flag; do
+ case "${flag}" in
+ d) device=${OPTARG} ;;
+ s) sign=${OPTARG} ;;
+ p) package=${OPTARG} ;;
+ *)
+ echo "usage: $0 [-d] [-s] [-p]" >&2
+ exit 1
+ ;;
+ esac
+done
+
+if [ -z "$package" ]; then
+ echo "Specify package"
+ exit 1;
+fi
+
+## Update dependency
+$FLUTTER pub get
+
+## Generate internationalizing
+$FLUTTER pub run build_runner build --delete-conflicting-outputs
+
+## Build aurora example app
+{
+ $FLUTTER build aurora --release
+} || {
+ exit 1;
+}
+
+if [ -n "$sign" ]; then
+
+ key=$(ls "$sign"/*key.pem)
+
+ if [ -z "$key" ]; then
+ echo "Key *key.pem not found."
+ exit 1;
+ fi
+
+ cert=$(ls "$sign"/*cert.pem)
+
+ if [ -z "$cert" ]; then
+ echo "Key *cert.pem not found."
+ exit 1;
+ fi
+
+ ## Sign rpm system key
+ "$PSDK_DIR"/sdk-chroot rpmsign-external sign \
+ --key "$key" \
+ --cert "$cert" \
+ build/aurora/arm/release/RPMS/*.rpm
+fi
+
+if [ -n "$device" ]; then
+
+ IFS=':' read -ra ADDR <<< "$device"
+
+ D_IP="${ADDR[0]}"
+ D_PASS="${ADDR[1]}"
+
+ # shellcheck disable=SC2012
+ rpm=$(ls "$PWD"/build/aurora/arm/release/RPMS/*.rpm | sort -r | head -n 1)
+
+ # upload rpm
+ scp "$rpm" defaultuser@"$D_IP:/home/defaultuser/Downloads"
+
+ # install rpm
+ ssh -t defaultuser@"$D_IP" "echo $D_PASS | devel-su pkcon -y install-local /home/defaultuser/Downloads/$package*.rpm"
+
+ # run application
+ ssh -t defaultuser@"$D_IP" "/usr/bin/$package"
+fi