Browse Source

Merge branch 'shared_preferences' into 'master'

Shared preferences

See merge request non-oss/flutter/flutter-plugins!2
merge-requests/2/merge
Vitaliy Zarubin 2 years ago
parent
commit
2f81d92ef7
  1. 2
      .gitignore
  2. 7
      AUTHORS.md
  3. 83
      CODE_OF_CONDUCT.md
  4. 169
      CONTRIBUTING.md
  5. 30
      LICENSE.BSD-3-CLAUSE.md
  6. 5
      README.md
  7. 31
      packages/path_provider/path_provider_aurora/.gitignore
  8. 41
      packages/path_provider/path_provider_aurora/README.md
  9. 4
      packages/path_provider/path_provider_aurora/analysis_options.yaml
  10. 23
      packages/path_provider/path_provider_aurora/aurora/CMakeLists.txt
  11. 24
      packages/path_provider/path_provider_aurora/aurora/include/path_provider_aurora/path_provider_aurora_plugin.h
  12. 42
      packages/path_provider/path_provider_aurora/aurora/path_provider_aurora_plugin.cpp
  13. BIN
      packages/path_provider/path_provider_aurora/data/preview.png
  14. 44
      packages/path_provider/path_provider_aurora/example/.gitignore
  15. 16
      packages/path_provider/path_provider_aurora/example/README.md
  16. 29
      packages/path_provider/path_provider_aurora/example/analysis_options.yaml
  17. 1
      packages/path_provider/path_provider_aurora/example/aurora/.gitignore
  18. 47
      packages/path_provider/path_provider_aurora/example/aurora/CMakeLists.txt
  19. 12
      packages/path_provider/path_provider_aurora/example/aurora/desktop/com.example.path_provider_aurora_example.desktop
  20. 16
      packages/path_provider/path_provider_aurora/example/aurora/flutter/generated_plugin_registrant.cpp
  21. 12
      packages/path_provider/path_provider_aurora/example/aurora/flutter/generated_plugin_registrant.h
  22. 32
      packages/path_provider/path_provider_aurora/example/aurora/flutter/generated_plugins.cmake
  23. BIN
      packages/path_provider/path_provider_aurora/example/aurora/icons/108x108.png
  24. BIN
      packages/path_provider/path_provider_aurora/example/aurora/icons/128x128.png
  25. BIN
      packages/path_provider/path_provider_aurora/example/aurora/icons/172x172.png
  26. BIN
      packages/path_provider/path_provider_aurora/example/aurora/icons/86x86.png
  27. 10
      packages/path_provider/path_provider_aurora/example/aurora/main.cpp
  28. 31
      packages/path_provider/path_provider_aurora/example/aurora/rpm/com.example.path_provider_aurora_example.spec
  29. 249
      packages/path_provider/path_provider_aurora/example/lib/main.dart
  30. 266
      packages/path_provider/path_provider_aurora/example/pubspec.lock
  31. 85
      packages/path_provider/path_provider_aurora/example/pubspec.yaml
  32. 27
      packages/path_provider/path_provider_aurora/example/test/widget_test.dart
  33. 81
      packages/path_provider/path_provider_aurora/lib/path_provider_aurora.dart
  34. 21
      packages/path_provider/path_provider_aurora/lib/path_provider_aurora_method_channel.dart
  35. 33
      packages/path_provider/path_provider_aurora/lib/path_provider_aurora_platform_interface.dart
  36. 32
      packages/path_provider/path_provider_aurora/pubspec.yaml
  37. 34
      packages/path_provider/path_provider_aurora/test/path_provider_aurora_method_channel_test.dart
  38. 30
      packages/shared_preferences/shared_preferences_aurora/.gitignore
  39. 30
      packages/shared_preferences/shared_preferences_aurora/.metadata
  40. 17
      packages/shared_preferences/shared_preferences_aurora/README.md
  41. 4
      packages/shared_preferences/shared_preferences_aurora/analysis_options.yaml
  42. 25
      packages/shared_preferences/shared_preferences_aurora/aurora/CMakeLists.txt
  43. 66
      packages/shared_preferences/shared_preferences_aurora/aurora/include/shared_preferences_aurora/shared_preferences_aurora_plugin.h
  44. 256
      packages/shared_preferences/shared_preferences_aurora/aurora/shared_preferences_aurora_plugin.cpp
  45. BIN
      packages/shared_preferences/shared_preferences_aurora/data/preview.png
  46. 44
      packages/shared_preferences/shared_preferences_aurora/example/.gitignore
  47. 16
      packages/shared_preferences/shared_preferences_aurora/example/README.md
  48. 29
      packages/shared_preferences/shared_preferences_aurora/example/analysis_options.yaml
  49. 1
      packages/shared_preferences/shared_preferences_aurora/example/aurora/.gitignore
  50. 47
      packages/shared_preferences/shared_preferences_aurora/example/aurora/CMakeLists.txt
  51. 12
      packages/shared_preferences/shared_preferences_aurora/example/aurora/desktop/com.example.shared_preferences_aurora_example.desktop
  52. 16
      packages/shared_preferences/shared_preferences_aurora/example/aurora/flutter/generated_plugin_registrant.cpp
  53. 12
      packages/shared_preferences/shared_preferences_aurora/example/aurora/flutter/generated_plugin_registrant.h
  54. 31
      packages/shared_preferences/shared_preferences_aurora/example/aurora/flutter/generated_plugins.cmake
  55. BIN
      packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/108x108.png
  56. BIN
      packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/128x128.png
  57. BIN
      packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/172x172.png
  58. BIN
      packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/86x86.png
  59. 10
      packages/shared_preferences/shared_preferences_aurora/example/aurora/main.cpp
  60. 31
      packages/shared_preferences/shared_preferences_aurora/example/aurora/rpm/com.example.shared_preferences_aurora_example.spec
  61. 197
      packages/shared_preferences/shared_preferences_aurora/example/lib/main.dart
  62. 299
      packages/shared_preferences/shared_preferences_aurora/example/pubspec.lock
  63. 84
      packages/shared_preferences/shared_preferences_aurora/example/pubspec.yaml
  64. 27
      packages/shared_preferences/shared_preferences_aurora/example/test/widget_test.dart
  65. 64
      packages/shared_preferences/shared_preferences_aurora/lib/shared_preferences_aurora.dart
  66. 82
      packages/shared_preferences/shared_preferences_aurora/lib/shared_preferences_aurora_method_channel.dart
  67. 58
      packages/shared_preferences/shared_preferences_aurora/lib/shared_preferences_aurora_platform_interface.dart
  68. 26
      packages/shared_preferences/shared_preferences_aurora/pubspec.yaml
  69. 71
      packages/shared_preferences/shared_preferences_aurora/test/shared_preferences_aurora_method_channel_test.dart
  70. 30
      packages/sqflite/sqflite_aurora/.gitignore
  71. 26
      packages/sqflite/sqflite_aurora/README.md
  72. 118
      packages/sqflite/sqflite_aurora/aurora/.clang-format
  73. 28
      packages/sqflite/sqflite_aurora/aurora/CMakeLists.txt
  74. 38
      packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/asynq.h
  75. 57
      packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/constants.h
  76. 111
      packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/database.h
  77. 40
      packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/logger.h
  78. 67
      packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/sqflite_aurora_plugin.h
  79. 41
      packages/sqflite/sqflite_aurora/aurora/lib/asynq.cpp
  80. 631
      packages/sqflite/sqflite_aurora/aurora/lib/database.cpp
  81. 44
      packages/sqflite/sqflite_aurora/aurora/lib/logger.cpp
  82. 619
      packages/sqflite/sqflite_aurora/aurora/lib/sqflite_aurora_plugin.cpp
  83. BIN
      packages/sqflite/sqflite_aurora/data/preview.png
  84. 45
      packages/sqflite/sqflite_aurora/example/.gitignore
  85. 25
      packages/sqflite/sqflite_aurora/example/LICENSE
  86. 9
      packages/sqflite/sqflite_aurora/example/README.md
  87. 87
      packages/sqflite/sqflite_aurora/example/analysis_options.yaml
  88. BIN
      packages/sqflite/sqflite_aurora/example/assets/example.db
  89. BIN
      packages/sqflite/sqflite_aurora/example/assets/issue_64.db
  90. 1
      packages/sqflite/sqflite_aurora/example/aurora/.gitignore
  91. 47
      packages/sqflite/sqflite_aurora/example/aurora/CMakeLists.txt
  92. 12
      packages/sqflite/sqflite_aurora/example/aurora/desktop/com.example.sqflite_aurora_example.desktop
  93. 16
      packages/sqflite/sqflite_aurora/example/aurora/flutter/generated_plugin_registrant.cpp
  94. 12
      packages/sqflite/sqflite_aurora/example/aurora/flutter/generated_plugin_registrant.h
  95. 31
      packages/sqflite/sqflite_aurora/example/aurora/flutter/generated_plugins.cmake
  96. BIN
      packages/sqflite/sqflite_aurora/example/aurora/icons/108x108.png
  97. BIN
      packages/sqflite/sqflite_aurora/example/aurora/icons/128x128.png
  98. BIN
      packages/sqflite/sqflite_aurora/example/aurora/icons/172x172.png
  99. BIN
      packages/sqflite/sqflite_aurora/example/aurora/icons/86x86.png
  100. 10
      packages/sqflite/sqflite_aurora/example/aurora/main.cpp
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

@ -0,0 +1,2 @@
/.idea/
/.vscode/

7
AUTHORS.md

@ -0,0 +1,7 @@
# Authors
* Denis Glazkov, <d.glazkov@omp.ru>
* Product owner, 2023
* Maintainer, 2023
* Vitaliy Zarubin, <v.zarubin@omp.ru>

83
CODE_OF_CONDUCT.md

@ -0,0 +1,83 @@
# Code of Conduct
## What is this code of conduct for?
Code of conduct is a current set of rules of the Open Mobile Platform
which informs you how we expect
the members of the Open Mobile Platform community
will interact while contributing and communicating.
We are committed to providing a friendly, safe and welcoming
environment for all, regardless of gender, gender identity and expression,
sexual orientation, ability, physical appearance, body size, race, age,
socioeconomic status, religion (or lack thereof),
or other marginalized aspect of community members.
We expect all members of the Open Mobile Platform community
to abide by this Code of Conduct whenever interacting
in Open Mobile Platform venues
(merge requests, pull requests, issues, 1-1 or group chat, meetups, conferences, etc.)
## Examples of appropriate behavior
* Using welcoming and inclusive language.
* Being respectful of differing viewpoints and experiences.
* Gracefully accepting constructive criticism.
* Focusing on what is best for the community.
* Showing empathy towards other community members.
## Examples of inappropriate behavior
Because we come from a variety of backgrounds,
we do not want to assume that everyone has the same assumptions
about what is and is not appropriate.
Here are some examples of inappropriate behavior
that are incompatible with our community's ethos:
* spamming, trolling, intentionally disrupting conversations,
or irrelevant solicitation or advertisement;
* making demeaning or discriminatory comments;
* making negative assumptions about someone's background,
abilities, or intentions;
* harassing or stalking individuals (online or in person).
In general: treat others how you would like to be treated,
were you in their place.
Do ask questions.
Do keep conflicts productively focused on technical issues.
Do remember that we are all people, not robots,
and all equally deserving of sensitivity and respect.
## What will organizers do about inappropriate behavior?
If we notice you doing or saying something inappropriate,
an organizer will ask you to stop.
We will not demonize you.
But please do stop the inappropriate behavior
so we can get back to writing and discussing code in a safe environment.
If you have philosophical disagreements about what is actually inappropriate,
please take them to a separate public or private conversation
with an Open Mobile Platform maintainer
so we don't turn pull requests into an ethics debate.
If you keep doing unacceptable things,
we will likely ban you, report you to the administration,
or take other appropriate action.
## What if I see or am subject to what feels like inappropriate behavior?
Let us know.
Please notify a community organizer as soon as possible.
Full contact information is listed in the Contact Info section of this document.
All communications will be kept strictly confidential,
unless otherwise required by law.
No issue will be considered too inconsequential or unimportant for us
to have a conversation about.
## Contact Info
If you need to report an incident,
please contact <community@omp.ru>.
This work is licensed under a Creative Commons Attribution 3.0 Unported License
For attribution requirements:
«Open Mobile Platform Code of Conduct»
Copyright (c) 2021 Open Mobile Platform LLC,
used under a [Creative Commons Attribution Unported license](http://creativecommons.org/licenses/by/3.0/).

169
CONTRIBUTING.md

@ -0,0 +1,169 @@
# Contributor License Agreements
Thank you for your interest in contributing
to software projects managed by Open Mobile Platform («We» or «Us»).
This contributor agreement («Agreement»)
documents the rights granted by contributors to Us.
To make this document effective,
please sign it and send it to Us by email or electronic submission.
This is a legally binding document,
so please read it carefully before agreeing to it.
The Agreement may cover more than one software project managed by Us.
## 1. Definitions
**«We» or «Us»** means Open Mobile Platform Limited Liability Company
(Open Mobile Platform LLC),
420500, Republic of Tatarstan, Verkhneuslonsky District,
Innopolis, Universitetskaya Street, h. 7, office 59,
OGRN (Primary State Registration Number) 1161690087020.
**«You»** means the individual who Submits a Contribution to Us.
**«Contribution»** means any work of authorship
that is Submitted by You to Us
in which You own or assert ownership of the Copyright.
**«Copyright»** means all rights protecting works of authorship
owned or controlled by You,
including copyright, moral and neighboring rights, as appropriate,
for the full term of their existence including any extensions by You.
**«Material»** means the work of authorship
which is made available by Us to third parties.
When this Agreement covers more than one software project,
the Material means the work of authorship
to which the Contribution was Submitted.
After You Submit the Contribution,
it may be included in the Material.
**«Submit»** means any form of electronic, verbal, or written communication
sent to Us or our representatives,
including but not limited to electronic mailing lists,
source code control systems, and issue tracking systems
that are managed by, or on behalf of, Us
for the purpose of discussing and improving the Material,
but excluding communication that is conspicuously marked
or otherwise designated in writing by You as «Not a Contribution».
**«Submission Date»** means the date
on which You Submit a Contribution to Us.
**«Effective Date»** means the date You execute this Agreement
or the date You first Submit a Contribution to Us,
whichever is earlier.
**«Media»** means any portion of a Contribution which is not software.
## 2. Grant of Rights
### 2.1. Copyright License
(a) You retain ownership of the Copyright in Your Contribution
and have the same rights to use or license the Contribution
which You would have had without entering into the Agreement.
(b) To the maximum extent permitted by the relevant law,
You grant to Us a perpetual, worldwide, non-exclusive,
transferable, royalty-free, irrevocable license
under the Copyright covering the Contribution,
with the right to sublicense
such rights through multiple tiers of sublicensees,
to reproduce, modify, display, perform and distribute
the Contribution as part of the Material;
provided that this license is conditioned upon compliance with Section 2.3.
### 2.2. Patent License
For patent claims including, without limitation,
method, process, and apparatus claims
which You own, control or have the right to grant, now or in the future,
You grant to Us a perpetual, worldwide, non-exclusive,
transferable, royalty-free, irrevocable patent license,
with the right to sublicense these rights to multiple tiers of sublicensees,
to make, have made, use, sell, offer for sale, import
and otherwise transfer the Contribution
and the Contribution in combination with the Material
(and portions of such combination).
This license is granted only to the extent
that the exercise of the licensed rights infringes such patent claims;
and provided that this license is conditioned upon compliance with Section 2.3.
### 2.3. Outbound License
Based on the grant of rights in Sections 2.1 and 2.2,
if We include Your Contribution in a Material,
We may license the Contribution under any license,
including copyleft, permissive, commercial, or proprietary licenses.
As a condition on the exercise of this right,
We agree to also license the Contribution
under the terms of the license or licenses
which We are using for the Material on the Submission Date.
### 2.4. Our Rights
You acknowledge that We are not obligated
to use Your Contribution as part of the Material
and may decide to include any Contribution We consider appropriate.
## 3. Agreement
You confirm that:
(a) You have the legal authority to enter into this Agreement.
(b) You own the Copyright and patent claims
covering the Contribution which are required
to grant the rights under Section 2.
(c) The grant of rights under Section 2
does not violate any grant of rights
which You have made to third parties, including Your employer.
If You are an employee,
You have had Your employer approve this Agreement
or sign the Entity version of this document.
If You are less than eighteen years old,
please have Your parents or guardian sign the Agreement.
## 4. Disclaimer
EXCEPT FOR THE EXPRESS WARRANTIES IN SECTION 3,
THE CONTRIBUTION IS PROVIDED «AS IS».
MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES
INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE
AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US.
TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED,
SUCH WARRANTY IS LIMITED IN DURATION TO THE MINIMUM PERIOD PERMITTED BY LAW.
## 5. Miscellaneous
5.1. This Agreement will be governed by and construed
in accordance with the laws of Russian Federation.
5.2. This Agreement sets out the entire agreement between You
and Us for Your Contributions to Us
and overrides all other agreements or understandings.
5.3. If You or We assign the rights or obligations
received through this Agreement to a third party,
as a condition of the assignment,
that third party must agree in writing
to abide by all the rights and obligations in the Agreement.
5.4. The failure of either party to require performance
by the other party of any provision of this Agreement in one situation
shall not affect the right of a party
to require such performance at any time in the future.
A waiver of performance under a provision in one situation
shall not be considered a waiver of the performance
of the provision in the future or a waiver of the provision in its entirety.
5.5. If any provision of this Agreement is found void and unenforceable,
such provision will be replaced to the extent possible with a provision
that comes closest to the meaning of the original provision
and which is enforceable.
The terms and conditions set forth in this Agreement
shall apply notwithstanding any failure of essential purpose
of this Agreement or any limited remedy
to the maximum extent possible under law.

30
LICENSE.BSD-3-CLAUSE.md

@ -0,0 +1,30 @@
# The 3-Clause BSD License
_Copyright (C) 2022 ru.auroraos_
Redistribution and use in source and binary forms,
with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain
the above copyright notice, this list of conditions and the following disclaimer.
2. 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.
3. Neither the name of the copyright holder nor the names of its 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 HOLDER 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.

5
README.md

@ -0,0 +1,5 @@
# Flutter Packages Aurora OS
This repo is a companion repo to the main flutter repo.
It contains the source code for Aurora Flutter's packages (i.e., packages developed by the Aurora team).
Check the packages directory to see all packages.

31
packages/path_provider/path_provider_aurora/.gitignore vendored

@ -0,0 +1,31 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/
/.metadata

41
packages/path_provider/path_provider_aurora/README.md

@ -0,0 +1,41 @@
# path_provider_aurora
The Aurora OS implementation of [`path_provider`](https://pub.dev/packages/path_provider).
Documentation for setting permissions can be found [here](https://developer.auroraos.ru/doc/software_development/reference/user_data).
## Usage
This package is not an _endorsed_ implementation of `path_provider`.
Therefore, you have to include `path_provider_aurora` alongside `path_provider` as dependencies in your `pubspec.yaml` file.
```yaml
dependencies:
path_provider: ^2.0.14
path_provider_aurora: ^0.0.0 # @todo Not published
```
Then you can import `path_provider` in your Dart code:
```dart
import 'package:path_provider/path_provider.dart';
```
## Supported APIs
- [x] `getTemporaryDirectory`
- [ ] `getApplicationSupportDirectory`
- [ ] `getLibraryDirectory`
- [x] `getApplicationDocumentsDirectory`
- [ ] `getExternalStorageDirectory`
- [ ] `getExternalCacheDirectories`
- [x] `getExternalStorageDirectories` (There is no concept of External in Aurora OS, but this interface allows you to get the pictures/music/movies directory)
- [x] `getDownloadsDirectory`
## Extra methods
PathProviderAurora.getApplicationOrg();
PathProviderAurora.getApplicationName();
### Preview example
![preview.png](data%2Fpreview.png)

4
packages/path_provider/path_provider_aurora/analysis_options.yaml

@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

23
packages/path_provider/path_provider_aurora/aurora/CMakeLists.txt

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.10)
set(PROJECT_NAME path_provider_aurora)
set(PLUGIN_NAME path_provider_aurora_platform_plugin)
project(${PROJECT_NAME} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-psabi")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
find_package(PkgConfig REQUIRED)
pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder)
add_library(${PLUGIN_NAME} SHARED path_provider_aurora_plugin.cpp)
set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::FlutterEmbedder)
target_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions(${PLUGIN_NAME} PRIVATE PLUGIN_IMPL)

24
packages/path_provider/path_provider_aurora/aurora/include/path_provider_aurora/path_provider_aurora_plugin.h

@ -0,0 +1,24 @@
#ifndef FLUTTER_PLUGIN_PATH_PROVIDER_AURORA_PLUGIN_H
#define FLUTTER_PLUGIN_PATH_PROVIDER_AURORA_PLUGIN_H
#include <flutter/plugin-interface.h>
#ifdef PLUGIN_IMPL
#define PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define PLUGIN_EXPORT
#endif
class PLUGIN_EXPORT PathProviderAuroraPlugin final : public PluginInterface
{
public:
void RegisterWithRegistrar(PluginRegistrar &registrar) override;
private:
void onMethodCall(const MethodCall &call);
void onGetApplicationOrg(const MethodCall &call);
void onGetApplicationName(const MethodCall &call);
void unimplemented(const MethodCall &call);
};
#endif /* FLUTTER_PLUGIN_PATH_PROVIDER_AURORA_PLUGIN_H */

42
packages/path_provider/path_provider_aurora/aurora/path_provider_aurora_plugin.cpp

@ -0,0 +1,42 @@
#include <path_provider_aurora/path_provider_aurora_plugin.h>
#include <flutter/method-channel.h>
#include <flutter/application.h>
#include <sys/utsname.h>
void PathProviderAuroraPlugin::RegisterWithRegistrar(PluginRegistrar &registrar)
{
registrar.RegisterMethodChannel("path_provider_aurora",
MethodCodecType::Standard,
[this](const MethodCall &call) { this->onMethodCall(call); });
}
void PathProviderAuroraPlugin::onMethodCall(const MethodCall &call)
{
const auto &method = call.GetMethod();
if (method == "getApplicationOrg") {
onGetApplicationOrg(call);
return;
}
else if (method == "getApplicationName") {
onGetApplicationName(call);
return;
}
unimplemented(call);
}
void PathProviderAuroraPlugin::onGetApplicationOrg(const MethodCall &call)
{
call.SendSuccessResponse(Application::GetID().orgname);
}
void PathProviderAuroraPlugin::onGetApplicationName(const MethodCall &call)
{
call.SendSuccessResponse(Application::GetID().appname);
}
void PathProviderAuroraPlugin::unimplemented(const MethodCall &call)
{
call.SendSuccessResponse(nullptr);
}

BIN
packages/path_provider/path_provider_aurora/data/preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

44
packages/path_provider/path_provider_aurora/example/.gitignore vendored

@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

16
packages/path_provider/path_provider_aurora/example/README.md

@ -0,0 +1,16 @@
# path_provider_aurora_example
Demonstrates how to use the path_provider_aurora plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

29
packages/path_provider/path_provider_aurora/example/analysis_options.yaml

@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

1
packages/path_provider/path_provider_aurora/example/aurora/.gitignore vendored

@ -0,0 +1 @@
flutter/ephemeral

47
packages/path_provider/path_provider_aurora/example/aurora/CMakeLists.txt

@ -0,0 +1,47 @@
cmake_minimum_required(VERSION 3.10)
project(com.example.path_provider_aurora_example LANGUAGES CXX)
include(GNUInstallDirs)
set(BINARY_NAME ${CMAKE_PROJECT_NAME})
set(FLUTTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/flutter)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_SKIP_RPATH OFF)
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../share/${BINARY_NAME}/lib")
find_package(PkgConfig REQUIRED)
pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder)
add_executable(${BINARY_NAME} main.cpp ${FLUTTER_DIR}/generated_plugin_registrant.cpp)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::FlutterEmbedder)
target_include_directories(${BINARY_NAME} PRIVATE ${FLUTTER_DIR})
include(flutter/generated_plugins.cmake)
set(PACKAGE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/${BINARY_NAME})
set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/applications)
set(ICONS_INSTALL_ROOT_DIR ${CMAKE_INSTALL_DATADIR}/icons/hicolor)
add_custom_command(TARGET ${BINARY_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libflutter-embedder.so
${PROJECT_BINARY_DIR}/bundle/lib/libflutter-embedder.so)
install(FILES ${PROJECT_BINARY_DIR}/bundle/icudtl.dat DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/flutter_assets DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/lib DESTINATION ${PACKAGE_INSTALL_DIR})
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES desktop/${BINARY_NAME}.desktop DESTINATION ${DESKTOP_INSTALL_DIR})
foreach(ICONS_SIZE 86x86 108x108 128x128 172x172)
install(FILES icons/${ICONS_SIZE}.png
RENAME ${BINARY_NAME}.png
DESTINATION ${ICONS_INSTALL_ROOT_DIR}/${ICONS_SIZE}/apps/)
endforeach(ICONS_SIZE)

12
packages/path_provider/path_provider_aurora/example/aurora/desktop/com.example.path_provider_aurora_example.desktop

@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
Name=path_provider_aurora_example
Comment=Demonstrates how to use the path_provider_aurora plugin.
Icon=com.example.path_provider_aurora_example
Exec=/usr/bin/com.example.path_provider_aurora_example
X-Nemo-Application-Type=silica-qt5
[X-Application]
Permissions=UserDirs
OrganizationName=com.example
ApplicationName=path_provider_aurora_example

16
packages/path_provider/path_provider_aurora/example/aurora/flutter/generated_plugin_registrant.cpp

@ -0,0 +1,16 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include <flutter/application.h>
#include <path_provider_aurora/path_provider_aurora_plugin.h>
#include "generated_plugin_registrant.h"
void RegisterPlugins() {
Application::RegisterPlugins({
std::make_shared<PathProviderAuroraPlugin>(),
});
}

12
packages/path_provider/path_provider_aurora/example/aurora/flutter/generated_plugin_registrant.h

@ -0,0 +1,12 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT
#define GENERATED_PLUGIN_REGISTRANT
void RegisterPlugins();
#endif /* GENERATED_PLUGIN_REGISTRANT */

32
packages/path_provider/path_provider_aurora/example/aurora/flutter/generated_plugins.cmake

@ -0,0 +1,32 @@
#
# Generated file, do not edit.
#
set(ROOT_PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}")
function(add_library TARGET)
_add_library(${TARGET} ${ARGN})
if(NOT "${TARGET}" MATCHES "^PkgConfig::.*")
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<TARGET_FILE:${TARGET}>"
"${ROOT_PROJECT_BINARY_DIR}/bundle/lib/$<TARGET_FILE_NAME:${TARGET}>")
endif(NOT "${TARGET}" MATCHES "^PkgConfig::.*")
endfunction()
list(APPEND FLUTTER_PLATFORM_PLUGIN_LIST
path_provider_aurora
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
xdga_directories
)
foreach(PLUGIN ${FLUTTER_PLATFORM_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${PLUGIN}/aurora plugins/${PLUGIN})
target_link_libraries(${BINARY_NAME} PRIVATE ${PLUGIN}_platform_plugin)
endforeach(PLUGIN)
foreach(FFI_PLUGIN ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${FFI_PLUGIN}/aurora plugins/${FFI_PLUGIN})
endforeach(FFI_PLUGIN)

BIN
packages/path_provider/path_provider_aurora/example/aurora/icons/108x108.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
packages/path_provider/path_provider_aurora/example/aurora/icons/128x128.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
packages/path_provider/path_provider_aurora/example/aurora/icons/172x172.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
packages/path_provider/path_provider_aurora/example/aurora/icons/86x86.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

10
packages/path_provider/path_provider_aurora/example/aurora/main.cpp

@ -0,0 +1,10 @@
#include <flutter/application.h>
#include "generated_plugin_registrant.h"
int main(int argc, char *argv[]) {
Application::Initialize(argc, argv);
Application::SetPixelRatio(1.8);
RegisterPlugins();
Application::Launch();
return 0;
}

31
packages/path_provider/path_provider_aurora/example/aurora/rpm/com.example.path_provider_aurora_example.spec

@ -0,0 +1,31 @@
%global __provides_exclude_from ^%{_datadir}/%{name}/lib/.*$
%global __requires_exclude ^lib(dconf|flutter-embedder|maliit-glib|appmanifest-.+|.+_platform_plugin)\\.so.*$
Name: com.example.path_provider_aurora_example
Summary: Demonstrates how to use the path_provider_aurora plugin.
Version: 0.1.0
Release: 1
License: Proprietary
Source0: %{name}-%{version}.tar.zst
BuildRequires: cmake
BuildRequires: pkgconfig(flutter-embedder)
%description
%{summary}.
%prep
%autosetup
%build
%cmake -DCMAKE_BUILD_TYPE=%{_flutter_build_type}
%make_build
%install
%make_install
%files
%{_bindir}/%{name}
%{_datadir}/%{name}/*
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png

249
packages/path_provider/path_provider_aurora/example/lib/main.dart

@ -0,0 +1,249 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path_provider_aurora/path_provider_aurora.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? _error;
String? _applicationOrg;
String? _applicationName;
String? _pathApplicationSupportDirectory;
String? _pathTempDirectory;
String? _pathApplicationDocumentsPath;
String? _pathDownloadsPath;
String? _pathPictures;
String? _pathMusic;
String? _pathMovies;
@override
void initState() {
super.initState();
loadPathDirectory();
}
/// Asynchronous function receiving directory paths
Future<void> loadPathDirectory() async {
try {
// Get names
String? applicationOrg = await PathProviderAurora.getApplicationOrg();
String? applicationName = await PathProviderAurora.getApplicationName();
// Get directories
Directory? applicationSupportDirectory = await getApplicationSupportDirectory();
Directory? tempDirectory = await getTemporaryDirectory();
Directory? pathApplicationDocumentsPath = await getApplicationDocumentsDirectory();
Directory? pathDownloadsPath = await getDownloadsDirectory();
List<Directory>? pathPictures = await getExternalStorageDirectories(type: StorageDirectory.pictures);
List<Directory>? pathMusic = await getExternalStorageDirectories(type: StorageDirectory.music);
List<Directory>? pathMovies = await getExternalStorageDirectories(type: StorageDirectory.movies);
// Update state variable
setState(() {
_applicationOrg = applicationOrg;
_applicationName = applicationName;
_pathApplicationSupportDirectory = applicationSupportDirectory.path;
_pathTempDirectory = tempDirectory.path;
_pathApplicationDocumentsPath = pathApplicationDocumentsPath.path;
_pathDownloadsPath = pathDownloadsPath?.path;
_pathPictures = pathPictures?.first.path;
_pathMusic = pathMusic?.first.path;
_pathMovies = pathMovies?.first.path;
});
} on Exception catch (e) {
setState(() {
_error = e.toString();
});
}
}
@override
Widget build(BuildContext context) {
const textStyleWhite = TextStyle(fontSize: 18, color: Colors.white);
const textStyleTitle = TextStyle(fontSize: 20, color: Colors.black);
const textStylePath = TextStyle(fontSize: 18, color: Colors.black54);
const spaceMedium = SizedBox(height: 20);
const spaceSmall = SizedBox(height: 10);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Example path_provider'),
),
body: Stack(
children: [
// Error message
Visibility(
visible: _error != null,
child: Center(
child: Padding(
padding: const EdgeInsets.all(16),
child: Container(
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
color: Colors.redAccent,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
child: Text(
_error ?? '',
style: textStyleWhite,
),
),
),
),
),
// List directories path
Visibility(
visible: _error == null,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Center(
child: Column(
children: [
// Info
Container(
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
child: const Text(
'Demo application demonstration implementation of path_provider',
style: textStyleWhite,
textAlign: TextAlign.center,
),
),
const SizedBox(height: 30),
// ApplicationOrg
const Text(
'Application Org',
style: textStyleTitle,
),
spaceSmall,
Text(
_applicationOrg ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// ApplicationName
const Text(
'Application Name',
style: textStyleTitle,
),
spaceSmall,
Text(
_applicationName ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// TempDirectory
const Text(
'ApplicationSupportDirectory',
style: textStyleTitle,
),
spaceSmall,
Text(
_pathApplicationSupportDirectory ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// TempDirectory
const Text(
'TempDirectory',
style: textStyleTitle,
),
spaceSmall,
Text(
_pathTempDirectory ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// ApplicationDocumentsPath
const Text(
'ApplicationDocumentsPath',
style: textStyleTitle,
),
spaceSmall,
Text(
_pathApplicationDocumentsPath ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// DownloadsPath
const Text(
'DownloadsPath',
style: textStyleTitle,
),
spaceSmall,
Text(
_pathDownloadsPath ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// Pictures
const Text(
'Pictures',
style: textStyleTitle,
),
spaceSmall,
Text(
_pathPictures ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// Music
const Text(
'Music',
style: textStyleTitle,
),
spaceSmall,
Text(
_pathMusic ?? 'Not found.',
style: textStylePath,
),
spaceMedium,
// Movies
const Text(
'Movies',
style: textStyleTitle,
),
spaceSmall,
Text(
_pathMovies ?? 'Not found.',
style: textStylePath,
),
],
),
),
),
),
),
],
),
),
);
}
}

266
packages/path_provider/path_provider_aurora/example/pubspec.lock

@ -0,0 +1,266 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.16.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.14"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.26"
path_provider_aurora:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.0.1"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.2"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.10"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.7"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.12"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.6.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
xdga_directories:
dependency: transitive
description:
path: "../../../xdga_directories"
relative: false
source: path
version: "0.0.1"
sdks:
dart: ">=2.18.6 <3.0.0"
flutter: ">=3.3.0"

85
packages/path_provider/path_provider_aurora/example/pubspec.yaml

@ -0,0 +1,85 @@
name: path_provider_aurora_example
description: Demonstrates how to use the path_provider_aurora plugin.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: '>=2.18.6 <3.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
path_provider: ^2.0.7
path_provider_aurora:
# When depending on this package from a real application you should use:
# path_provider_aurora: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

27
packages/path_provider/path_provider_aurora/example/test/widget_test.dart

@ -0,0 +1,27 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider_aurora_example/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) => widget is Text &&
widget.data!.startsWith('Running on:'),
),
findsOneWidget,
);
});
}

81
packages/path_provider/path_provider_aurora/lib/path_provider_aurora.dart

@ -0,0 +1,81 @@
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:xdga_directories/xdga_directories.dart' as xdga_directories;
import 'package:path/path.dart' as p;
import 'path_provider_aurora_platform_interface.dart';
/// The aurora implementation of [PathProviderPlatform]
///
/// This class implements the `package:path_provider` functionality for Aurora.
class PathProviderAurora extends PathProviderPlatform {
/// Registers this class as the default instance of [PathProviderPlatform]
static void registerWith() {
PathProviderPlatform.instance = PathProviderAurora();
}
/// Get application name
static Future<String?> getApplicationName() {
return PathProviderAuroraPlatform.instance.getApplicationName();
}
/// Get application org
static Future<String?> getApplicationOrg() {
return PathProviderAuroraPlatform.instance.getApplicationOrg();
}
/// Path to a directory where the application may place application support files.
@override
Future<String?> getApplicationSupportPath() async {
String? org = await getApplicationOrg();
String? name = await getApplicationName();
// QStandardPaths::AppDataLocation
return p.join(xdga_directories.getAppDataLocation(), org, name);
}
/// Path to the temporary directory on the device that is not backed up and is
/// suitable for storing caches of downloaded files.
@override
Future<String> getTemporaryPath() async {
String? org = await getApplicationOrg();
String? name = await getApplicationName();
// QStandardPaths::CacheLocation
return p.join(xdga_directories.getCacheLocation(), org, name);
}
/// Path to a directory where the application may place data that is
/// user-generated, or that cannot otherwise be recreated by your application.
@override
Future<String> getApplicationDocumentsPath() async {
// QStandardPaths::DocumentsLocation
return xdga_directories.getDocumentsLocation();
}
/// Path to the directory where downloaded files can be stored.
/// This is typically only relevant on desktop operating systems.
@override
Future<String> getDownloadsPath() async {
// QStandardPaths::DownloadLocation
return xdga_directories.getDownloadLocation();
}
/// Paths to directories where application specific data can be stored.
/// These paths typically reside on external storage like separate partitions
/// or SD cards. Phones may have multiple storage directories available.
@override
Future<List<String>?> getExternalStoragePaths({
/// Optional parameter. See [StorageDirectory] for more informations on
/// how this type translates to Android storage directories.
StorageDirectory? type,
}) async {
switch (type) {
case StorageDirectory.pictures:
return [xdga_directories.getPicturesLocation()]; // QStandardPaths::PicturesLocation
case StorageDirectory.music:
return [xdga_directories.getMusicLocation()]; // QStandardPaths::MusicLocation
case StorageDirectory.movies:
return [xdga_directories.getMoviesLocation()]; // QStandardPaths::MoviesLocation
default:
throw UnimplementedError('Type "$type" not supported.');
}
}
}

21
packages/path_provider/path_provider_aurora/lib/path_provider_aurora_method_channel.dart

@ -0,0 +1,21 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'path_provider_aurora_platform_interface.dart';
/// An implementation of [PathProviderAuroraPlatform] that uses method channels.
class MethodChannelPathProviderAurora extends PathProviderAuroraPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('path_provider_aurora');
@override
Future<String?> getApplicationOrg() async {
return await methodChannel.invokeMethod<String>('getApplicationOrg');
}
@override
Future<String?> getApplicationName() async {
return await methodChannel.invokeMethod<String>('getApplicationName');
}
}

33
packages/path_provider/path_provider_aurora/lib/path_provider_aurora_platform_interface.dart

@ -0,0 +1,33 @@
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'path_provider_aurora_method_channel.dart';
abstract class PathProviderAuroraPlatform extends PlatformInterface {
/// Constructs a PathProviderAuroraPlatform.
PathProviderAuroraPlatform() : super(token: _token);
static final Object _token = Object();
static PathProviderAuroraPlatform _instance = MethodChannelPathProviderAurora();
/// The default instance of [PathProviderAuroraPlatform] to use.
///
/// Defaults to [MethodChannelPathProviderAurora].
static PathProviderAuroraPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [PathProviderAuroraPlatform] when
/// they register themselves.
static set instance(PathProviderAuroraPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Future<String?> getApplicationOrg() {
throw UnimplementedError('getApplicationOrg() has not been implemented.');
}
Future<String?> getApplicationName() {
throw UnimplementedError('getApplicationName() has not been implemented.');
}
}

32
packages/path_provider/path_provider_aurora/pubspec.yaml

@ -0,0 +1,32 @@
name: path_provider_aurora
description: The Aurora OS implementation of path_provider.
version: 0.0.1
homepage: https://os-git.omprussia.ru/non-oss/flutter/flutter-plugins/packages/xdga_directories
environment:
sdk: '>=2.18.6 <3.0.0'
flutter: ">=2.5.0"
flutter:
plugin:
implements: path_provider
platforms:
aurora:
dartPluginClass: PathProviderAurora
pluginClass: PathProviderAuroraPlugin
dependencies:
flutter:
sdk: flutter
path: ^1.8.2
plugin_platform_interface: ^2.0.2
path_provider_platform_interface: ^2.0.6
xdga_directories:
path: ../../xdga_directories
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0

34
packages/path_provider/path_provider_aurora/test/path_provider_aurora_method_channel_test.dart

@ -0,0 +1,34 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider_aurora/path_provider_aurora_method_channel.dart';
void main() {
MethodChannelPathProviderAurora platform = MethodChannelPathProviderAurora();
const MethodChannel channel = MethodChannel('path_provider_aurora');
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async {
switch (methodCall.method) {
case 'getApplicationOrg':
return 'com.example';
case 'getApplicationName':
return 'path_provider_aurora';
}
return '';
});
});
tearDown(() {
channel.setMockMethodCallHandler(null);
});
test('onGetApplicationOrg', () async {
expect(await platform.getApplicationOrg(), 'com.example');
});
test('onGetApplicationName', () async {
expect(await platform.getApplicationName(), 'path_provider_aurora');
});
}

30
packages/shared_preferences/shared_preferences_aurora/.gitignore vendored

@ -0,0 +1,30 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/

30
packages/shared_preferences/shared_preferences_aurora/.metadata

@ -0,0 +1,30 @@
# 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.
version:
revision: 135454af32477f815a7525073027a3ff9eff1bfd
channel: unknown
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
- platform: aurora
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

17
packages/shared_preferences/shared_preferences_aurora/README.md

@ -0,0 +1,17 @@
# shared_preferences_aurora
The Aurora implementation of [`shared_preferences`][https://pub.dev/packages/shared_preferences].
## Usage
This package is not an _endorsed_ implementation of `shared_preferences`.
Therefore, you have to include `path_provider_aurora` alongside `shared_preferences` as dependencies in your `pubspec.yaml` file.
```yaml
dependencies:
shared_preferences: ^2.1.1
shared_preferences_aurora: ^0.0.0 # @todo Not published
```
### Preview example
![preview.png](data%2Fpreview.png)

4
packages/shared_preferences/shared_preferences_aurora/analysis_options.yaml

@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

25
packages/shared_preferences/shared_preferences_aurora/aurora/CMakeLists.txt

@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.10)
set(PROJECT_NAME shared_preferences_aurora)
set(PLUGIN_NAME shared_preferences_aurora_platform_plugin)
project(${PROJECT_NAME} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-psabi")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
find_package(PkgConfig REQUIRED)
pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder)
pkg_check_modules(Qt5Core REQUIRED IMPORTED_TARGET Qt5Core)
add_library(${PLUGIN_NAME} SHARED shared_preferences_aurora_plugin.cpp)
set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::FlutterEmbedder)
target_link_libraries(${PLUGIN_NAME} PUBLIC PkgConfig::Qt5Core)
target_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions(${PLUGIN_NAME} PRIVATE PLUGIN_IMPL)

66
packages/shared_preferences/shared_preferences_aurora/aurora/include/shared_preferences_aurora/shared_preferences_aurora_plugin.h

@ -0,0 +1,66 @@
#ifndef FLUTTER_PLUGIN_SHARED_PREFERENCES_AURORA_PLUGIN_H
#define FLUTTER_PLUGIN_SHARED_PREFERENCES_AURORA_PLUGIN_H
#include <flutter/plugin-interface.h>
#include <flutter/method-channel.h>
#include <QSettings>
#include <QString>
#ifdef PLUGIN_IMPL
#define PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define PLUGIN_EXPORT
#endif
class PLUGIN_EXPORT SharedPreferencesAuroraPlugin final : public PluginInterface
{
public:
SharedPreferencesAuroraPlugin();
void RegisterWithRegistrar(PluginRegistrar &registrar) override;
struct ARGS
{
QString prefix;
QString key;
Encodable value;
};
enum Types
{
Int,
Bool,
Double,
String,
List
};
enum Methods
{
setInt,
setBool,
setDouble,
setString,
setStringList,
clearWithPrefix,
remove,
getAllWithPrefix,
};
private:
void onMethodCall(const MethodCall &call);
void unimplemented(const MethodCall &call);
ARGS getArguments(const MethodCall &call);
void onSetInt(const MethodCall &call);
void onSetBool(const MethodCall &call);
void onSetDouble(const MethodCall &call);
void onSetString(const MethodCall &call);
void onSetStringList(const MethodCall &call);
void onClearWithPrefix(const MethodCall &call);
void onRemove(const MethodCall &call);
void onGetAllWithPrefix(const MethodCall &call);
QSettings settings;
std::map <std::string, int> mapping;
};
#endif /* FLUTTER_PLUGIN_SHARED_PREFERENCES_AURORA_PLUGIN_H */

256
packages/shared_preferences/shared_preferences_aurora/aurora/shared_preferences_aurora_plugin.cpp

@ -0,0 +1,256 @@
#include <shared_preferences_aurora/shared_preferences_aurora_plugin.h>
#include <flutter/method-channel.h>
#include <flutter/application.h>
#include <QSettings>
#include <QVariant>
#include <QDir>
namespace {
QString defaultSettingsFile()
{
const auto [orgname, appname] = Application::GetID();
return QStringLiteral("%1/.local/share/%2/%3/.flutter_shared_preferences.conf")
.arg(QDir::homePath())
.arg(QString::fromStdString(orgname))
.arg(QString::fromStdString(appname));
}
} /* namespace */
SharedPreferencesAuroraPlugin::SharedPreferencesAuroraPlugin(): settings(
defaultSettingsFile(),
QSettings::NativeFormat
) {
// map methods
this->mapping = std::map <std::string, int>({
{"setInt", Methods::setInt},
{"setBool", Methods::setBool},
{"setDouble", Methods::setDouble},
{"setString", Methods::setString},
{"setStringList", Methods::setStringList},
{"clearWithPrefix", Methods::clearWithPrefix},
{"remove", Methods::remove},
{"getAllWithPrefix", Methods::getAllWithPrefix},
});
}
void SharedPreferencesAuroraPlugin::RegisterWithRegistrar(PluginRegistrar &registrar)
{
registrar.RegisterMethodChannel("shared_preferences_aurora",
MethodCodecType::Standard,
[this](const MethodCall &call) { this->onMethodCall(call); });
}
SharedPreferencesAuroraPlugin::ARGS SharedPreferencesAuroraPlugin::getArguments(const MethodCall &call)
{
QString key = QString::fromStdString(call.GetArguments()["key"].GetString());
Encodable value = call.GetArguments()["value"];
ARGS args;
args.prefix = key.split('.').first();
args.key = key.mid(args.prefix.length() + 1, key.length());
args.value = value;
return args;
}
void SharedPreferencesAuroraPlugin::onMethodCall(const MethodCall &call)
{
const auto &method = call.GetMethod();
switch (this->mapping[method])
{
case Methods::setInt:
onSetInt(call);
return;
case Methods::setBool:
onSetBool(call);
return;
case Methods::setDouble:
onSetDouble(call);
return;
case Methods::setString:
onSetString(call);
return;
case Methods::setStringList:
onSetStringList(call);
return;
case Methods::clearWithPrefix:
onClearWithPrefix(call);
return;
case Methods::remove:
onRemove(call);
return;
case Methods::getAllWithPrefix:
onGetAllWithPrefix(call);
return;
}
unimplemented(call);
}
void SharedPreferencesAuroraPlugin::onSetInt(const MethodCall &call)
{
const auto [prefix, key, value] = this->getArguments(call);
settings.beginGroup(prefix);
settings.setValue(
QStringLiteral("%1:").arg(Types::Int) + key,
value.GetInt()
);
settings.sync();
settings.endGroup();
call.SendSuccessResponse(true);
}
void SharedPreferencesAuroraPlugin::onSetBool(const MethodCall &call)
{
const auto [prefix, key, value] = this->getArguments(call);
settings.beginGroup(prefix);
settings.setValue(
QStringLiteral("%1:").arg(Types::Bool) + key,
value.GetBoolean()
);
settings.sync();
settings.endGroup();
call.SendSuccessResponse(true);
}
void SharedPreferencesAuroraPlugin::onSetDouble(const MethodCall &call)
{
const auto [prefix, key, value] = this->getArguments(call);
settings.beginGroup(prefix);
settings.setValue(
QStringLiteral("%1:").arg(Types::Double) + key,
value.GetFloat()
);
settings.sync();
settings.endGroup();
call.SendSuccessResponse(true);
}
void SharedPreferencesAuroraPlugin::onSetString(const MethodCall &call)
{
const auto [prefix, key, value] = this->getArguments(call);
settings.beginGroup(prefix);
settings.setValue(
QStringLiteral("%1:").arg(Types::String) + key,
QString::fromStdString(value.GetString())
);
settings.sync();
settings.endGroup();
call.SendSuccessResponse(true);
}
void SharedPreferencesAuroraPlugin::onSetStringList(const MethodCall &call)
{
const auto [prefix, key, value] = this->getArguments(call);
const auto vec = value.GetList();
QStringList strings;
for (const auto& item : vec)
{
strings.append(QString::fromStdString(item.GetString()));
}
settings.beginGroup(prefix);
settings.setValue(
QStringLiteral("%1:").arg(Types::List) + key,
strings
);
settings.sync();
settings.endGroup();
call.SendSuccessResponse(true);
}
void SharedPreferencesAuroraPlugin::onClearWithPrefix(const MethodCall &call)
{
const auto prefix = QString::fromStdString(call.GetArguments()["prefix"].GetString())
.replace(".", "");
settings.beginGroup(prefix);
settings.remove("");
settings.sync();
settings.endGroup();
call.SendSuccessResponse(true);
}
void SharedPreferencesAuroraPlugin::onRemove(const MethodCall &call)
{
QString raw = QString::fromStdString(call.GetArguments()["key"].GetString());
const auto prefix = raw.split('.').first();
const auto key = raw.mid(prefix.length() + 1, raw.length());
settings.beginGroup(prefix);
settings.remove(QStringLiteral("%1:").arg(Types::Int) + key);
settings.remove(QStringLiteral("%1:").arg(Types::Bool) + key);
settings.remove(QStringLiteral("%1:").arg(Types::Double) + key);
settings.remove(QStringLiteral("%1:").arg(Types::String) + key);
settings.remove(QStringLiteral("%1:").arg(Types::List) + key);
settings.sync();
settings.endGroup();
call.SendSuccessResponse(true);
}
void SharedPreferencesAuroraPlugin::onGetAllWithPrefix(const MethodCall &call)
{
const auto prefix = QString::fromStdString(call.GetArguments()["prefix"].GetString())
.replace(".", "");
std::map<Encodable, Encodable> map;
settings.beginGroup(prefix);
for (const auto& item : settings.allKeys())
{
const auto type = item.split(":").first();
const auto key = prefix + "." + item.mid(type.length() + 1, item.length());
const auto variant = settings.value(item);
switch (type.toInt())
{
case Types::Int:
map[key.toStdString()] = Encodable(variant.toInt());
break;
case Types::Bool:
map[key.toStdString()] = Encodable(variant.toBool());
break;
case Types::Double:
map[key.toStdString()] = Encodable(variant.toDouble());
break;
case Types::String:
map[key.toStdString()] = Encodable(variant.toString().toStdString());
break;
case Types::List:
std::vector<Encodable> vec;
QStringList list = variant.toStringList();
for (const auto& item : list)
{
vec.push_back(item.toStdString());
}
map[key.toStdString()] = vec;
}
}
settings.endGroup();
call.SendSuccessResponse(map);
}
void SharedPreferencesAuroraPlugin::unimplemented(const MethodCall &call)
{
call.SendSuccessResponse(nullptr);
}

BIN
packages/shared_preferences/shared_preferences_aurora/data/preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

44
packages/shared_preferences/shared_preferences_aurora/example/.gitignore vendored

@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

16
packages/shared_preferences/shared_preferences_aurora/example/README.md

@ -0,0 +1,16 @@
# shared_preferences_aurora_example
Demonstrates how to use the shared_preferences_aurora plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

29
packages/shared_preferences/shared_preferences_aurora/example/analysis_options.yaml

@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

1
packages/shared_preferences/shared_preferences_aurora/example/aurora/.gitignore vendored

@ -0,0 +1 @@
flutter/ephemeral

47
packages/shared_preferences/shared_preferences_aurora/example/aurora/CMakeLists.txt

@ -0,0 +1,47 @@
cmake_minimum_required(VERSION 3.10)
project(com.example.shared_preferences_aurora_example LANGUAGES CXX)
include(GNUInstallDirs)
set(BINARY_NAME ${CMAKE_PROJECT_NAME})
set(FLUTTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/flutter)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_SKIP_RPATH OFF)
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../share/${BINARY_NAME}/lib")
find_package(PkgConfig REQUIRED)
pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder)
add_executable(${BINARY_NAME} main.cpp ${FLUTTER_DIR}/generated_plugin_registrant.cpp)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::FlutterEmbedder)
target_include_directories(${BINARY_NAME} PRIVATE ${FLUTTER_DIR})
include(flutter/generated_plugins.cmake)
set(PACKAGE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/${BINARY_NAME})
set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/applications)
set(ICONS_INSTALL_ROOT_DIR ${CMAKE_INSTALL_DATADIR}/icons/hicolor)
add_custom_command(TARGET ${BINARY_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libflutter-embedder.so
${PROJECT_BINARY_DIR}/bundle/lib/libflutter-embedder.so)
install(FILES ${PROJECT_BINARY_DIR}/bundle/icudtl.dat DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/flutter_assets DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/lib DESTINATION ${PACKAGE_INSTALL_DIR})
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES desktop/${BINARY_NAME}.desktop DESTINATION ${DESKTOP_INSTALL_DIR})
foreach(ICONS_SIZE 86x86 108x108 128x128 172x172)
install(FILES icons/${ICONS_SIZE}.png
RENAME ${BINARY_NAME}.png
DESTINATION ${ICONS_INSTALL_ROOT_DIR}/${ICONS_SIZE}/apps/)
endforeach(ICONS_SIZE)

12
packages/shared_preferences/shared_preferences_aurora/example/aurora/desktop/com.example.shared_preferences_aurora_example.desktop

@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
Name=shared_preferences_aurora_example
Comment=Demonstrates how to use the shared_preferences_aurora plugin.
Icon=com.example.shared_preferences_aurora_example
Exec=/usr/bin/com.example.shared_preferences_aurora_example
X-Nemo-Application-Type=silica-qt5
[X-Application]
Permissions=
OrganizationName=com.example
ApplicationName=shared_preferences_aurora_example

16
packages/shared_preferences/shared_preferences_aurora/example/aurora/flutter/generated_plugin_registrant.cpp

@ -0,0 +1,16 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include <flutter/application.h>
#include <shared_preferences_aurora/shared_preferences_aurora_plugin.h>
#include "generated_plugin_registrant.h"
void RegisterPlugins() {
Application::RegisterPlugins({
std::make_shared<SharedPreferencesAuroraPlugin>(),
});
}

12
packages/shared_preferences/shared_preferences_aurora/example/aurora/flutter/generated_plugin_registrant.h

@ -0,0 +1,12 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT
#define GENERATED_PLUGIN_REGISTRANT
void RegisterPlugins();
#endif /* GENERATED_PLUGIN_REGISTRANT */

31
packages/shared_preferences/shared_preferences_aurora/example/aurora/flutter/generated_plugins.cmake

@ -0,0 +1,31 @@
#
# Generated file, do not edit.
#
set(ROOT_PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}")
function(add_library TARGET)
_add_library(${TARGET} ${ARGN})
if(NOT "${TARGET}" MATCHES "^PkgConfig::.*")
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<TARGET_FILE:${TARGET}>"
"${ROOT_PROJECT_BINARY_DIR}/bundle/lib/$<TARGET_FILE_NAME:${TARGET}>")
endif(NOT "${TARGET}" MATCHES "^PkgConfig::.*")
endfunction()
list(APPEND FLUTTER_PLATFORM_PLUGIN_LIST
shared_preferences_aurora
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
foreach(PLUGIN ${FLUTTER_PLATFORM_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${PLUGIN}/aurora plugins/${PLUGIN})
target_link_libraries(${BINARY_NAME} PRIVATE ${PLUGIN}_platform_plugin)
endforeach(PLUGIN)
foreach(FFI_PLUGIN ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${FFI_PLUGIN}/aurora plugins/${FFI_PLUGIN})
endforeach(FFI_PLUGIN)

BIN
packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/108x108.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/128x128.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/172x172.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
packages/shared_preferences/shared_preferences_aurora/example/aurora/icons/86x86.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

10
packages/shared_preferences/shared_preferences_aurora/example/aurora/main.cpp

@ -0,0 +1,10 @@
#include <flutter/application.h>
#include "generated_plugin_registrant.h"
int main(int argc, char *argv[]) {
Application::Initialize(argc, argv);
Application::SetPixelRatio(1.8);
RegisterPlugins();
Application::Launch();
return 0;
}

31
packages/shared_preferences/shared_preferences_aurora/example/aurora/rpm/com.example.shared_preferences_aurora_example.spec

@ -0,0 +1,31 @@
%global __provides_exclude_from ^%{_datadir}/%{name}/lib/.*$
%global __requires_exclude ^lib(dconf|flutter-embedder|maliit-glib|appmanifest-.+|.+_platform_plugin)\\.so.*$
Name: com.example.shared_preferences_aurora_example
Summary: Demonstrates how to use the shared_preferences_aurora plugin.
Version: 0.1.0
Release: 1
License: Proprietary
Source0: %{name}-%{version}.tar.zst
BuildRequires: cmake
BuildRequires: pkgconfig(flutter-embedder)
%description
%{summary}.
%prep
%autosetup
%build
%cmake -DCMAKE_BUILD_TYPE=%{_flutter_build_type}
%make_build
%install
%make_install
%files
%{_bindir}/%{name}
%{_datadir}/%{name}/*
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png

197
packages/shared_preferences/shared_preferences_aurora/example/lib/main.dart

@ -0,0 +1,197 @@
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int? _counter;
bool? _repeat;
double? _decimal;
String? _action;
List<String>? _items;
String? _error;
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
try {
final SharedPreferences prefs = await SharedPreferences.getInstance();
// Save an integer value to 'counter' key.
await prefs.setInt('counter', 10);
// Save an boolean value to 'repeat' key.
await prefs.setBool('repeat', true);
// Save an double value to 'decimal' key.
await prefs.setDouble('decimal', 1.5);
// Save an String value to 'action' key.
await prefs.setString('action', 'Start');
// Save an list of strings to 'items' key.
await prefs.setStringList('items', <String>['Earth', 'Moon', 'Sun']);
// Try reading data from the 'counter' key. If it doesn't exist, returns null.
final int? counter = prefs.getInt('counter');
// Try reading data from the 'repeat' key. If it doesn't exist, returns null.
final bool? repeat = prefs.getBool('repeat');
// Try reading data from the 'decimal' key. If it doesn't exist, returns null.
final double? decimal = prefs.getDouble('decimal');
// Try reading data from the 'action' key. If it doesn't exist, returns null.
final String? action = prefs.getString('action');
// Try reading data from the 'items' key. If it doesn't exist, returns null.
final List<String>? items = prefs.getStringList('items');
setState(() {
_counter = counter;
_repeat = repeat;
_decimal = decimal;
_action = action;
_items = items;
});
} on PlatformException {
setState(() {
_error = 'Platform exception';
});
}
}
@override
Widget build(BuildContext context) {
const textStyleWhite = TextStyle(fontSize: 18, color: Colors.white);
const textStyleTitle = TextStyle(fontSize: 20, color: Colors.black);
const textStylePath = TextStyle(fontSize: 18, color: Colors.black54);
const spaceMedium = SizedBox(height: 20);
const spaceSmall = SizedBox(height: 10);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Example shared_preferences'),
),
body: Stack(
children: [
// Error message
Visibility(
visible: _error != null,
child: Center(
child: Padding(
padding: const EdgeInsets.all(16),
child: Container(
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
color: Colors.redAccent,
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
child: Text(
_error ?? '',
style: textStyleWhite,
),
),
),
),
),
// List directories path
Visibility(
visible: _error == null,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Center(
child: Column(
children: [
// Info
Container(
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
color: Colors.green,
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
),
child: const Text(
'Demo application demonstration implementation of shared_preferences',
style: textStyleWhite,
textAlign: TextAlign.center,
),
),
const SizedBox(height: 30),
const Text(
'Counter / int',
style: textStyleTitle,
),
spaceSmall,
Text(
_counter.toString(),
style: textStylePath,
),
spaceMedium,
const Text(
'Repeat / bool',
style: textStyleTitle,
),
spaceSmall,
Text(
_repeat.toString(),
style: textStylePath,
),
spaceMedium,
const Text(
'Decimal / double',
style: textStyleTitle,
),
spaceSmall,
Text(
_decimal.toString(),
style: textStylePath,
),
spaceMedium,
const Text(
'Action / String',
style: textStyleTitle,
),
spaceSmall,
Text(
_action.toString(),
style: textStylePath,
),
spaceMedium,
const Text(
'Items / String List',
style: textStyleTitle,
),
spaceSmall,
Text(
_items.toString(),
style: textStylePath,
),
],
),
),
),
),
),
],
),
),
);
}
}

299
packages/shared_preferences/shared_preferences_aurora/example/pubspec.lock

@ -0,0 +1,299 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.16.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.4"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.10"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.6"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
shared_preferences_aurora:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.0.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.2"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.12"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.4"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
sdks:
dart: ">=2.18.6 <3.0.0"
flutter: ">=3.0.0"

84
packages/shared_preferences/shared_preferences_aurora/example/pubspec.yaml

@ -0,0 +1,84 @@
name: shared_preferences_aurora_example
description: Demonstrates how to use the shared_preferences_aurora plugin.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: '>=2.18.6 <3.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
shared_preferences: ^2.1.1
shared_preferences_aurora:
# When depending on this package from a real application you should use:
# shared_preferences_aurora: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

27
packages/shared_preferences/shared_preferences_aurora/example/test/widget_test.dart

@ -0,0 +1,27 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences_aurora_example/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) => widget is Text &&
widget.data!.startsWith('Running on:'),
),
findsOneWidget,
);
});
}

64
packages/shared_preferences/shared_preferences_aurora/lib/shared_preferences_aurora.dart

@ -0,0 +1,64 @@
import 'shared_preferences_aurora_platform_interface.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart';
class SharedPreferencesAurora extends SharedPreferencesStorePlatform {
SharedPreferencesAurora({
@visibleForTesting SharedPreferencesAuroraPlatform? api,
}) : _api = api ?? SharedPreferencesAuroraPlatform.instance;
late final SharedPreferencesAuroraPlatform _api;
/// Registers this class as the default instance of [SharedPreferencesStorePlatform].
static void registerWith() {
SharedPreferencesStorePlatform.instance = SharedPreferencesAurora();
}
static const String _defaultPrefix = 'flutter.';
@override
Future<bool> remove(String key) async {
return _api.remove(key);
}
@override
Future<bool> setValue(String valueType, String key, Object value) async {
switch (valueType) {
case 'String':
return _api.setString(key, value as String);
case 'Bool':
return _api.setBool(key, value as bool);
case 'Int':
return _api.setInt(key, value as int);
case 'Double':
return _api.setDouble(key, value as double);
case 'StringList':
return _api.setStringList(key, value as List<String>);
}
throw PlatformException(
code: 'InvalidOperation',
message: '"$valueType" is not a supported type.');
}
@override
Future<bool> clear() {
return clearWithPrefix(_defaultPrefix);
}
@override
Future<bool> clearWithPrefix(String prefix) async {
return _api.clearWithPrefix(prefix);
}
@override
Future<Map<String, Object>> getAll() {
return getAllWithPrefix(_defaultPrefix);
}
@override
Future<Map<String, Object>> getAllWithPrefix(String prefix) async {
final Map<Object?, Object?> data = await _api.getAllWithPrefix(prefix);
return data.cast<String, Object>();
}
}

82
packages/shared_preferences/shared_preferences_aurora/lib/shared_preferences_aurora_method_channel.dart

@ -0,0 +1,82 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'shared_preferences_aurora_platform_interface.dart';
/// An implementation of [SharedPreferencesAuroraPlatform] that uses method channels.
class MethodChannelSharedPreferencesAurora
extends SharedPreferencesAuroraPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('shared_preferences_aurora');
@override
Future<bool> setInt(String key, int value) async {
return await methodChannel.invokeMethod<bool?>('setInt', {
'key': key,
'value': value,
}) ??
false;
}
@override
Future<bool> setBool(String key, bool value) async {
return await methodChannel.invokeMethod<bool?>('setBool', {
'key': key,
'value': value,
}) ??
false;
}
@override
Future<bool> setDouble(String key, double value) async {
return await methodChannel.invokeMethod<bool?>('setDouble', {
'key': key,
'value': value,
}) ??
false;
}
@override
Future<bool> setString(String key, String value) async {
return await methodChannel.invokeMethod<bool?>('setString', {
'key': key,
'value': value,
}) ??
false;
}
@override
Future<bool> setStringList(String key, List<String> value) async {
return await methodChannel.invokeMethod<bool?>('setStringList', {
'key': key,
'value': value,
}) ??
false;
}
@override
Future<bool> clearWithPrefix(String prefix) async {
return await methodChannel.invokeMethod<bool?>('clearWithPrefix', {
'prefix': prefix,
}) ??
false;
}
@override
Future<bool> remove(String key) async {
return await methodChannel.invokeMethod<bool?>('remove', {
'key': key,
}) ??
false;
}
@override
Future<Map<Object?, Object?>> getAllWithPrefix(String prefix) async {
return await methodChannel
.invokeMethod<Map<Object?, Object?>?>('getAllWithPrefix', {
'prefix': prefix,
}) ??
{};
}
}

58
packages/shared_preferences/shared_preferences_aurora/lib/shared_preferences_aurora_platform_interface.dart

@ -0,0 +1,58 @@
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'shared_preferences_aurora_method_channel.dart';
abstract class SharedPreferencesAuroraPlatform extends PlatformInterface {
/// Constructs a SharedPreferencesAuroraPlatform.
SharedPreferencesAuroraPlatform() : super(token: _token);
static final Object _token = Object();
static SharedPreferencesAuroraPlatform _instance =
MethodChannelSharedPreferencesAurora();
/// The default instance of [SharedPreferencesAuroraPlatform] to use.
///
/// Defaults to [MethodChannelSharedPreferencesAurora].
static SharedPreferencesAuroraPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [SharedPreferencesAuroraPlatform] when
/// they register themselves.
static set instance(SharedPreferencesAuroraPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Future<bool> setInt(String key, int value) {
throw UnimplementedError('setInt() has not been implemented.');
}
Future<bool> setBool(String key, bool value) {
throw UnimplementedError('setBool() has not been implemented.');
}
Future<bool> setDouble(String key, double value) {
throw UnimplementedError('setDouble() has not been implemented.');
}
Future<bool> setString(String key, String value) {
throw UnimplementedError('setString() has not been implemented.');
}
Future<bool> setStringList(String key, List<String> value) {
throw UnimplementedError('setStringList() has not been implemented.');
}
Future<bool> clearWithPrefix(String prefix) {
throw UnimplementedError('onClearWithPrefix() has not been implemented.');
}
Future<bool> remove(String key) {
throw UnimplementedError('remove() has not been implemented.');
}
Future<Map<Object?, Object?>> getAllWithPrefix(String prefix) {
throw UnimplementedError('getAllWithPrefix() has not been implemented.');
}
}

26
packages/shared_preferences/shared_preferences_aurora/pubspec.yaml

@ -0,0 +1,26 @@
name: shared_preferences_aurora
description: The Aurora OS implementation of shared_preferences.
version: 0.0.1
homepage:
environment:
sdk: '>=2.18.6 <3.0.0'
flutter: ">=2.5.0"
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
shared_preferences_platform_interface: ^2.2.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
plugin:
platforms:
aurora:
pluginClass: SharedPreferencesAuroraPlugin
dartPluginClass: SharedPreferencesAurora

71
packages/shared_preferences/shared_preferences_aurora/test/shared_preferences_aurora_method_channel_test.dart

@ -0,0 +1,71 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences_aurora/shared_preferences_aurora_method_channel.dart';
void main() {
MethodChannelSharedPreferencesAurora platform =
MethodChannelSharedPreferencesAurora();
const MethodChannel channel = MethodChannel('shared_preferences_aurora');
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async {
switch (methodCall.method) {
case 'setInt':
return true;
case 'setBool':
return true;
case 'setDouble':
return true;
case 'setString':
return true;
case 'setStringList':
return true;
case 'clearWithPrefix':
return true;
case 'remove':
return true;
case 'getAllWithPrefix':
return <Object?, Object?>{};
}
return null;
});
});
tearDown(() {
channel.setMockMethodCallHandler(null);
});
test('onSetInt', () async {
expect(await platform.setInt('key', 42), true);
});
test('onSetBool', () async {
expect(await platform.setBool('key', true), true);
});
test('onSetDouble', () async {
expect(await platform.setDouble('key', 0.0), true);
});
test('onSetString', () async {
expect(await platform.setString('key', "Start"), true);
});
test('onSetStringList', () async {
expect(await platform.setStringList('key', <String>[]), true);
});
test('onClearWithPrefix', () async {
expect(await platform.clearWithPrefix('prefix'), true);
});
test('onRemove', () async {
expect(await platform.remove('key'), true);
});
test('onGetAllWithPrefix', () async {
expect(await platform.getAllWithPrefix('prefix'), <Object?, Object?>{});
});
}

30
packages/sqflite/sqflite_aurora/.gitignore vendored

@ -0,0 +1,30 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/

26
packages/sqflite/sqflite_aurora/README.md

@ -0,0 +1,26 @@
# sqflite_aurora
The Aurora OS implementation of [`sqflite`](https://pub.dev/packages/sqflite).
## Usage
This package is not an endorsed implementation of `sqflite`.
Therefore, you have to include `sqflite_aurora` alongside `sqflite` as dependencies in your `pubspec.yaml` file.
```yaml
dependencies:
sqflite: ^2.2.6
sqflite_aurora:
git: git@os-git.omprussia.ru:non-oss/flutter/flutter-plugins.git
path: packages/sqflite/sqflite_aurora
```
Then you can import and use `sqflite` in your Dart code:
```dart
import 'package:sqflite/sqflite.dart';
```
### Preview example
![preview.png](data%2Fpreview.png)

118
packages/sqflite/sqflite_aurora/aurora/.clang-format

@ -0,0 +1,118 @@
# .clang-format for Qt Creator
#
# This is for clang-format >= 5.0.
#
# The configuration below follows the Qt Creator Coding Rules [1] as closely as
# possible. For documentation of the options, see [2].
#
# Use ../../tests/manual/clang-format-for-qtc/test.cpp for documenting problems
# or testing changes.
#
# In case you update this configuration please also update the qtcStyle() in src\plugins\clangformat\clangformatutils.cpp
#
# [1] https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
# [2] https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: true
AlignEscapedNewlines: DontAlign
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- forever # avoids { wrapped to next line
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^<Q.*'
Priority: 200
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
# Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 150
PenaltyBreakBeforeFirstCallParameter: 300
PenaltyBreakComment: 500
PenaltyBreakFirstLessLess: 400
PenaltyBreakString: 600
PenaltyExcessCharacter: 50
PenaltyReturnTypeOnItsOwnLine: 300
PointerAlignment: Right
ReflowComments: false
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never

28
packages/sqflite/sqflite_aurora/aurora/CMakeLists.txt

@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.10)
set(PROJECT_NAME sqflite_aurora)
set(PLUGIN_NAME sqflite_aurora_platform_plugin)
project(${PROJECT_NAME} LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-psabi")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
find_package(PkgConfig REQUIRED)
pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder)
pkg_check_modules(SQLite REQUIRED IMPORTED_TARGET sqlite3)
add_library(${PLUGIN_NAME} SHARED
lib/asynq.cpp
lib/database.cpp
lib/logger.cpp
lib/sqflite_aurora_plugin.cpp)
set_target_properties(${PLUGIN_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::FlutterEmbedder PkgConfig::SQLite)
target_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_definitions(${PLUGIN_NAME} PRIVATE PLUGIN_IMPL)

38
packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/asynq.h

@ -0,0 +1,38 @@
#ifndef FLUTTER_PLUGIN_SQFLITE_ASYNC_QUEUE_H
#define FLUTTER_PLUGIN_SQFLITE_ASYNC_QUEUE_H
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>
#include <queue>
#ifdef PLUGIN_IMPL
#define PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define PLUGIN_EXPORT
#endif
class PLUGIN_EXPORT AsyncQueue final
{
public:
typedef std::function<void()> Task;
public:
AsyncQueue();
~AsyncQueue();
void Push(const Task &task);
private:
void run();
private:
bool m_running;
std::thread m_thread;
std::queue<Task> m_tasks;
std::mutex m_mutex;
std::condition_variable m_condition;
};
#endif /* FLUTTER_PLUGIN_SQFLITE_ASYNC_QUEUE_H */

57
packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/constants.h

@ -0,0 +1,57 @@
#ifndef FLUTTER_PLUGIN_SQFLITE_CONSTANTS_H
#define FLUTTER_PLUGIN_SQFLITE_CONSTANTS_H
#include <string>
const std::string METHOD_GET_PLATFORM_VERSION = "getPlatformVersion";
const std::string METHOD_GET_DATABASES_PATH = "getDatabasesPath";
const std::string METHOD_DEBUG = "debug";
const std::string METHOD_OPTIONS = "options";
const std::string METHOD_OPEN_DATABASE = "openDatabase";
const std::string METHOD_CLOSE_DATABASE = "closeDatabase";
const std::string METHOD_INSERT = "insert";
const std::string METHOD_EXECUTE = "execute";
const std::string METHOD_QUERY = "query";
const std::string METHOD_QUERY_CURSOR_NEXT = "queryCursorNext";
const std::string METHOD_UPDATE = "update";
const std::string METHOD_BATCH = "batch";
const std::string METHOD_DELETE_DATABASE = "deleteDatabase";
const std::string METHOD_DATABASE_EXISTS = "databaseExists";
const std::string ARG_ID = "id";
const std::string ARG_PATH = "path";
const std::string ARG_READ_ONLY = "readOnly";
const std::string ARG_SINGLE_INSTANCE = "singleInstance";
const std::string ARG_LOG_LEVEL = "logLevel";
const std::string ARG_TRANSACTION_ID = "transactionId";
const std::string ARG_IN_TRANSACTION = "inTransaction";
const std::string ARG_RECOVERED = "recovered";
const std::string ARG_RECOVERED_IN_TRANSACTION = "recoveredInTransaction";
const std::string ARG_SQL = "sql";
const std::string ARG_SQL_ARGUMENTS = "arguments";
const std::string ARG_NO_RESULT = "noResult";
const std::string ARG_CONTINUE_ON_ERROR = "continueOnError";
const std::string ARG_COLUMNS = "columns";
const std::string ARG_ROWS = "rows";
const std::string ARG_DATABASES = "databases";
const std::string ARG_COMMAND = "cmd";
const std::string ARG_OPERATIONS = "operations";
const std::string ARG_METHOD = "method";
const std::string ARG_RESULT = "result";
const std::string ARG_ERROR = "error";
const std::string ARG_ERROR_CODE = "code";
const std::string ARG_ERROR_MESSAGE = "message";
const std::string ARG_ERROR_DATA = "data";
const std::string ARG_CURSOR_PAGE_SIZE = "cursorPageSize";
const std::string ARG_CURSOR_ID = "cursorId";
const std::string ARG_CANCEL = "cancel";
const std::string ERROR_SQFLITE = "sqlite_error";
const std::string ERROR_OPEN = "open_failed";
const std::string ERROR_CLOSE = "close_failed";
const std::string ERROR_CLOSED = "database_closed";
const std::string ERROR_BAD_PARAM = "bad_param";
const std::string ERROR_BAD_ARGS = "bad_arguments";
const std::string ERROR_INTERNAL = "internal";
#endif /* FLUTTER_PLUGIN_SQFLITE_CONSTANTS_H */

111
packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/database.h

@ -0,0 +1,111 @@
#ifndef FLUTTER_PLUGIN_SQFLITE_DATABASE_H
#define FLUTTER_PLUGIN_SQFLITE_DATABASE_H
#include <flutter/encodable.h>
#include <flutter/method-call.h>
#include <sqflite_aurora/logger.h>
#include <functional>
#include <optional>
#include <sqlite3.h>
#include <string>
#include <unordered_map>
#include <queue>
#ifdef PLUGIN_IMPL
#define PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define PLUGIN_EXPORT
#endif
class PLUGIN_EXPORT Database final
{
public:
enum TransactionID {
None = -2,
Force = -1,
};
struct Cursor
{
int64_t id;
sqlite3_stmt *stmt;
int64_t pageSize;
};
struct Operation
{
std::string method;
std::string sql;
Encodable::List arguments;
};
public:
Database(int id, const std::string &path, bool singleton, const Logger &logger);
~Database();
public:
std::optional<std::string> Open();
std::optional<std::string> OpenReadOnly();
std::optional<std::string> Close();
std::optional<std::string> Execute(const std::string &sql, const Encodable::List &args);
std::optional<std::string> QueryCursorNext(int cursorID, bool cancel, Encodable::Map &result);
std::optional<std::string> Query(const std::string &sql,
const Encodable::List &args,
Encodable::Map &result);
std::optional<std::string> QueryWithPageSize(const std::string &sql,
const Encodable::List &args,
int64_t pageSize,
Encodable::Map &result);
std::optional<std::string> Insert(const std::string &sql,
const Encodable::List &args,
int &insertID);
std::optional<std::string> Update(const std::string &sql,
const Encodable::List &args,
int &updated);
std::optional<std::string> Batch(const std::vector<Operation> &operations,
bool continueOnError,
Encodable::List &results);
void EnterInTransaction();
void LeaveTransaction();
int CurrentTransactionID();
typedef std::function<void()> SqlCommandCallback;
void ProcessSqlCommand(int transactionID, const SqlCommandCallback &callback);
public:
bool IsOpen() const;
bool IsSingleInstance() const;
bool IsInTransaction() const;
bool IsInMemory() const;
bool IsReadOnly() const;
const std::string &Path() const;
int64_t ID() const;
Logger::Level LogLevel() const;
private:
std::string currentErrorMessage();
std::optional<std::string> createParentDir();
std::optional<std::string> bindStmtArgs(sqlite3_stmt *stmt, const Encodable::List &args);
void closeCursor(const Cursor &cursor);
std::optional<std::string> resultFromCursor(const Cursor &cursor, Encodable::Map &result);
private:
int64_t id;
std::string path;
bool isSingleInstance;
bool isReadOnly;
Logger logger;
int transactionID;
int currentTransactionID;
std::queue<SqlCommandCallback> pendingSqlCallbacks;
int64_t cursorID;
std::unordered_map<int64_t, Cursor> cursors;
sqlite3 *db;
};
#endif /* FLUTTER_PLUGIN_SQFLITE_DATABASE_H */

40
packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/logger.h

@ -0,0 +1,40 @@
#ifndef FLUTTER_PLUGIN_SQFLITE_LOGGER_H
#define FLUTTER_PLUGIN_SQFLITE_LOGGER_H
#include <flutter/logger.h>
#include <string>
#ifdef PLUGIN_IMPL
#define PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define PLUGIN_EXPORT
#endif
class PLUGIN_EXPORT Logger final
{
public:
enum Level {
None = 0,
Sql,
Verbose,
};
public:
Logger(Level level, const std::string &tag);
Level LogLevel() const;
void SetLogLevel(Level level);
std::string Tag() const;
void SetTag(const std::string &tag);
std::ostream &verb();
std::ostream &sql();
private:
Level level;
std::string tag;
std::ostream devnull;
};
#endif /* FLUTTER_PLUGIN_SQFLITE_LOGGER_H */

67
packages/sqflite/sqflite_aurora/aurora/include/sqflite_aurora/sqflite_aurora_plugin.h

@ -0,0 +1,67 @@
#ifndef FLUTTER_PLUGIN_SQFLITE_H
#define FLUTTER_PLUGIN_SQFLITE_H
#include <flutter/plugin-interface.h>
#include <sqflite_aurora/asynq.h>
#include <sqflite_aurora/database.h>
#include <memory>
#include <mutex>
#include <unordered_map>
#ifdef PLUGIN_IMPL
#define PLUGIN_EXPORT __attribute__((visibility("default")))
#else
#define PLUGIN_EXPORT
#endif
class PLUGIN_EXPORT SqfliteAuroraPlugin final : public PluginInterface
{
public:
SqfliteAuroraPlugin();
void RegisterWithRegistrar(PluginRegistrar &registrar) override;
private:
void onMethodCall(const MethodCall &call);
void onPlatformVersionCall(const MethodCall &call);
void onOpenDatabaseCall(const MethodCall &call);
void onCloseDatabaseCall(const MethodCall &call);
void onDeleteDatabaseCall(const MethodCall &call);
void onDatabaseExistsCall(const MethodCall &call);
void onGetDatabasesPathCall(const MethodCall &call);
void onOptionsCall(const MethodCall &call);
void onDebugCall(const MethodCall &call);
void onExecuteCall(const MethodCall &call);
void onQueryCall(const MethodCall &call);
void onQueryCursorNextCall(const MethodCall &call);
void onUpdateCall(const MethodCall &call);
void onInsertCall(const MethodCall &call);
void onBatchCall(const MethodCall &call);
std::shared_ptr<Database> databaseByPath(const std::string &path);
std::shared_ptr<Database> databaseByID(int64_t id);
void databaseRemove(std::shared_ptr<Database> db);
void databaseAdd(std::shared_ptr<Database> db);
void success(const MethodCall &call, const Encodable &result = nullptr);
void error(const MethodCall &call,
const std::string &error,
const std::string &message,
const std::string &desc = "",
const Encodable &details = nullptr);
Encodable::Map makeOpenResult(int64_t dbID, bool recovered, bool recoveredInTransaction);
private:
std::mutex mutex;
std::unordered_map<std::string, std::shared_ptr<Database>> singletonDatabases;
std::unordered_map<int64_t, std::shared_ptr<Database>> databases;
int64_t dbID = 0;
Logger logger;
bool queryAsMapList = false;
AsyncQueue asynq;
};
#endif /* FLUTTER_PLUGIN_SQFLITE_H */

41
packages/sqflite/sqflite_aurora/aurora/lib/asynq.cpp

@ -0,0 +1,41 @@
#include <sqflite_aurora/asynq.h>
AsyncQueue::AsyncQueue()
: m_running(false)
, m_thread()
{}
AsyncQueue::~AsyncQueue()
{
m_running = false;
m_thread.join();
}
void AsyncQueue::Push(const Task &task)
{
if (!m_running) {
m_running = true;
m_tasks.push(task);
m_thread = std::thread(&AsyncQueue::run, this);
return;
}
std::lock_guard<std::mutex> lock(m_mutex);
m_tasks.push(task);
m_condition.notify_one();
}
void AsyncQueue::run()
{
while (m_running) {
std::unique_lock<std::mutex> lock(m_mutex);
m_condition.wait(lock, [this] { return !m_tasks.empty(); });
const auto task = m_tasks.front();
m_tasks.pop();
lock.unlock();
task();
}
}

631
packages/sqflite/sqflite_aurora/aurora/lib/database.cpp

@ -0,0 +1,631 @@
#include <sqflite_aurora/constants.h>
#include <sqflite_aurora/database.h>
#include <filesystem>
#include <limits>
namespace {
void addError(Encodable::List &results, const std::string &error)
{
results.emplace_back(Encodable::Map{
{"error", Encodable::Map{{"message", error}}},
});
}
template<typename T>
void addResult(Encodable::List &results, const T &result)
{
results.emplace_back(Encodable::Map{{"result", result}});
}
} /* namespace */
Database::Database(int id, const std::string &path, bool singleton, const Logger &logger)
: id(id)
, path(path)
, isSingleInstance(singleton)
, logger(logger.LogLevel(), logger.Tag() + "-db-" + std::to_string(id))
, transactionID(0)
, currentTransactionID(TransactionID::None)
, cursorID(0)
, db(nullptr)
{}
Database::~Database()
{
Close();
}
std::optional<std::string> Database::Open()
{
const auto error = this->createParentDir();
if (error)
return error;
int result_code = sqlite3_open_v2(this->path.c_str(),
&this->db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
nullptr);
if (result_code != SQLITE_OK)
return this->currentErrorMessage();
this->isReadOnly = false;
return std::nullopt;
}
std::optional<std::string> Database::OpenReadOnly()
{
const auto error = this->createParentDir();
if (error)
return error;
int result_code = sqlite3_open_v2(this->path.c_str(), &this->db, SQLITE_OPEN_READONLY, nullptr);
if (result_code != SQLITE_OK)
return this->currentErrorMessage();
this->isReadOnly = true;
return std::nullopt;
}
std::optional<std::string> Database::Close()
{
if (sqlite3_close_v2(this->db) != SQLITE_OK)
return this->currentErrorMessage();
this->db = nullptr;
this->pendingSqlCallbacks = {};
return std::nullopt;
}
std::optional<std::string> Database::Execute(const std::string &sql, const Encodable::List &args)
{
sqlite3_stmt *stmt = nullptr;
if (sqlite3_prepare_v2(this->db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK)
return this->currentErrorMessage();
const auto error = this->bindStmtArgs(stmt, args);
if (error) {
sqlite3_finalize(stmt);
return error;
}
while (true) {
int status = sqlite3_step(stmt);
if (status == SQLITE_ROW)
continue;
if (status == SQLITE_DONE)
break;
sqlite3_finalize(stmt);
return this->currentErrorMessage();
}
sqlite3_finalize(stmt);
return std::nullopt;
}
std::optional<std::string> Database::Query(const std::string &sql,
const Encodable::List &args,
Encodable::Map &result)
{
sqlite3_stmt *stmt = nullptr;
if (sqlite3_prepare_v2(this->db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK)
return this->currentErrorMessage();
const auto error = this->bindStmtArgs(stmt, args);
if (error) {
sqlite3_finalize(stmt);
return error;
}
Encodable::List columns;
for (int idx = 0; idx < sqlite3_column_count(stmt); idx++)
columns.emplace_back(sqlite3_column_name(stmt, idx));
Encodable::List rows;
while (true) {
int status = sqlite3_step(stmt);
if (status == SQLITE_ROW) {
Encodable::List row;
for (size_t idx = 0; idx < columns.size(); idx++) {
switch (sqlite3_column_type(stmt, idx)) {
case SQLITE_INTEGER:
row.emplace_back(sqlite3_column_int64(stmt, idx));
break;
case SQLITE_FLOAT:
row.emplace_back(sqlite3_column_double(stmt, idx));
break;
case SQLITE_TEXT:
row.emplace_back(reinterpret_cast<const char *>(sqlite3_column_text(stmt, idx)));
break;
case SQLITE_BLOB: {
const uint8_t *blob = reinterpret_cast<const uint8_t *>(
sqlite3_column_blob(stmt, idx));
std::vector<uint8_t> v(blob, blob + sqlite3_column_bytes(stmt, idx));
row.emplace_back(v);
break;
}
case SQLITE_NULL: {
const char *columnDecltype = sqlite3_column_decltype(stmt, idx);
if (columnDecltype != NULL && std::string("BLOB") == columnDecltype)
row.emplace_back(Encodable::Uint8List{});
else
row.emplace_back(nullptr);
break;
}
default:
break;
}
}
rows.emplace_back(row);
continue;
}
if (status == SQLITE_DONE)
break;
sqlite3_finalize(stmt);
return this->currentErrorMessage();
}
result = Encodable::Map{{"columns", columns}, {"rows", rows}};
sqlite3_finalize(stmt);
return std::nullopt;
}
std::optional<std::string> Database::QueryWithPageSize(const std::string &sql,
const Encodable::List &args,
int64_t pageSize,
Encodable::Map &result)
{
sqlite3_stmt *stmt = nullptr;
if (sqlite3_prepare_v2(this->db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK)
return this->currentErrorMessage();
const auto error = this->bindStmtArgs(stmt, args);
if (error)
return error;
this->cursorID += 1;
this->cursors[cursorID] = Cursor{this->cursorID, stmt, pageSize};
return resultFromCursor(this->cursors[cursorID], result);
}
std::optional<std::string> Database::QueryCursorNext(int cursorID,
bool cancel,
Encodable::Map &result)
{
this->logger.verb() << "querying cursor next (ID=" << cursorID << "; CANCEL=" << cancel << ")"
<< std::endl;
if (!this->cursors.count(cursorID))
return "cursor not found";
const Cursor &cursor = this->cursors[cursorID];
if (cancel) {
this->closeCursor(cursor);
return std::nullopt;
}
return this->resultFromCursor(cursor, result);
}
std::optional<std::string> Database::Insert(const std::string &sql,
const Encodable::List &args,
int &insertID)
{
if (this->isReadOnly)
return "database is readonly";
const auto error = this->Execute(sql, args);
if (error)
return error;
const int updated = sqlite3_changes(this->db);
this->logger.sql() << "rows updated: " << updated << std::endl;
if (updated == 0) {
insertID = 0;
return std::nullopt;
}
insertID = sqlite3_last_insert_rowid(this->db);
this->logger.sql() << "last inserted row id: " << insertID << std::endl;
return std::nullopt;
}
std::optional<std::string> Database::Update(const std::string &sql,
const Encodable::List &args,
int &updated)
{
if (this->isReadOnly)
return "database is readonly";
const auto error = this->Execute(sql, args);
if (error)
return error;
updated = sqlite3_changes(this->db);
this->logger.sql() << "rows updated: " << updated << std::endl;
return std::nullopt;
}
void Database::ProcessSqlCommand(int transactionID, const SqlCommandCallback &callback)
{
if (this->currentTransactionID == TransactionID::None) {
callback();
return;
}
if (transactionID == this->currentTransactionID || transactionID == TransactionID::Force) {
callback();
if (this->currentTransactionID == TransactionID::None) {
while (!this->pendingSqlCallbacks.empty() && this->IsOpen()) {
const auto &pendingCallback = this->pendingSqlCallbacks.front();
pendingCallback();
this->pendingSqlCallbacks.pop();
}
}
return;
}
this->pendingSqlCallbacks.push(callback);
}
void Database::EnterInTransaction()
{
this->transactionID += 1;
this->currentTransactionID = this->transactionID;
}
void Database::LeaveTransaction()
{
this->currentTransactionID = TransactionID::None;
}
int Database::CurrentTransactionID()
{
return this->currentTransactionID;
}
bool Database::IsOpen() const
{
return this->db != nullptr;
}
const std::string &Database::Path() const
{
return this->path;
}
bool Database::IsSingleInstance() const
{
return this->isSingleInstance;
}
bool Database::IsReadOnly() const
{
return this->isReadOnly;
}
bool Database::IsInTransaction() const
{
return this->currentTransactionID != TransactionID::None;
}
int64_t Database::ID() const
{
return this->id;
}
Logger::Level Database::LogLevel() const
{
return this->logger.LogLevel();
}
bool Database::IsInMemory() const
{
return this->path.empty() || this->path == ":memory:";
}
std::string Database::currentErrorMessage()
{
const auto message = sqlite3_errmsg(this->db);
const auto code = sqlite3_extended_errcode(this->db);
return std::string(message) + " (" + std::to_string(code) + ")";
}
std::optional<std::string> Database::createParentDir()
{
if (this->IsInMemory())
return std::nullopt;
const auto parentDir = std::filesystem::path(this->path).parent_path();
if (std::filesystem::exists(parentDir))
return std::nullopt;
if (std::filesystem::create_directories(parentDir))
return std::nullopt;
return "couldn't create parent directory";
}
std::optional<std::string> Database::bindStmtArgs(sqlite3_stmt *stmt, const Encodable::List &args)
{
int result = SQLITE_OK;
for (size_t i = 0; i < args.size(); i++) {
auto idx = i + 1;
auto &arg = args[i];
if (arg.IsNull()) {
result = sqlite3_bind_null(stmt, idx);
} else if (arg.IsBoolean()) {
result = sqlite3_bind_int(stmt, idx, static_cast<int>(arg.GetBoolean()));
} else if (arg.IsInt()) {
const int64_t value = arg.GetInt();
const int32_t i32min = std::numeric_limits<int32_t>::min();
const int32_t i32max = std::numeric_limits<int32_t>::max();
if (value < i32min || value > i32max)
result = sqlite3_bind_int64(stmt, idx, arg.GetInt());
else
result = sqlite3_bind_int64(stmt, idx, static_cast<int32_t>(arg.GetInt()));
} else if (arg.IsFloat()) {
result = sqlite3_bind_double(stmt, idx, arg.GetFloat());
} else if (arg.IsString()) {
const auto &string = arg.GetString();
result = sqlite3_bind_text(stmt, idx, string.c_str(), string.size(), SQLITE_TRANSIENT);
} else if (arg.IsUint8List()) {
const auto &container = arg.GetUint8List();
result = sqlite3_bind_blob(stmt,
idx,
container.data(),
container.size(),
SQLITE_TRANSIENT);
} else if (arg.IsInt32List()) {
const auto &container = arg.GetInt32List();
result = sqlite3_bind_blob(stmt,
idx,
container.data(),
container.size() * sizeof(int32_t),
SQLITE_TRANSIENT);
} else if (arg.IsInt64List()) {
const auto &container = arg.GetInt64List();
result = sqlite3_bind_blob(stmt,
idx,
container.data(),
container.size() * sizeof(int64_t),
SQLITE_TRANSIENT);
} else if (arg.IsFloat32List()) {
const auto &container = arg.GetFloat32List();
result = sqlite3_bind_blob(stmt,
idx,
container.data(),
container.size() * sizeof(float),
SQLITE_TRANSIENT);
} else if (arg.IsFloat64List()) {
const auto &container = arg.GetFloat64List();
result = sqlite3_bind_blob(stmt,
idx,
container.data(),
container.size() * sizeof(double),
SQLITE_TRANSIENT);
} else if (arg.IsList()) {
/* only bytes list is supported */
std::vector<uint8_t> container;
for (const auto &entry : arg.GetList()) {
if (!entry.IsInt())
return "only list of bytes is supported for statement parameter";
const auto value = entry.GetInt();
if (value < 0 || value > 255)
return "only list of bytes is supported for statement parameter";
container.push_back(static_cast<uint8_t>(value));
}
result = sqlite3_bind_blob(stmt,
idx,
container.data(),
container.size(),
SQLITE_TRANSIENT);
} else {
return "statement parameter has invalid type";
}
if (result != SQLITE_OK)
return this->currentErrorMessage();
}
this->logger.sql() << sqlite3_expanded_sql(stmt) << std::endl;
return std::nullopt;
}
void Database::closeCursor(const Cursor &cursor)
{
logger.verb() << "closing cursor (ID=" << cursor.id << ")" << std::endl;
sqlite3_finalize(cursor.stmt);
this->cursors.erase(cursor.id);
}
std::optional<std::string> Database::resultFromCursor(const Cursor &cursor, Encodable::Map &result)
{
Encodable::List columns;
for (int idx = 0; idx < sqlite3_column_count(cursor.stmt); idx++)
columns.emplace_back(sqlite3_column_name(cursor.stmt, idx));
Encodable::List rows;
int status = SQLITE_ROW;
while (static_cast<int64_t>(rows.size()) < cursor.pageSize) {
status = sqlite3_step(cursor.stmt);
if (status == SQLITE_ROW) {
Encodable::List row;
for (size_t idx = 0; idx < columns.size(); idx++) {
switch (sqlite3_column_type(cursor.stmt, idx)) {
case SQLITE_INTEGER:
row.emplace_back(sqlite3_column_int64(cursor.stmt, idx));
break;
case SQLITE_FLOAT:
row.emplace_back(sqlite3_column_double(cursor.stmt, idx));
break;
case SQLITE_TEXT:
row.emplace_back(
reinterpret_cast<const char *>(sqlite3_column_text(cursor.stmt, idx)));
break;
case SQLITE_BLOB: {
const uint8_t *blob = reinterpret_cast<const uint8_t *>(
sqlite3_column_blob(cursor.stmt, idx));
std::vector<uint8_t> v(blob, blob + sqlite3_column_bytes(cursor.stmt, idx));
row.emplace_back(v);
break;
}
case SQLITE_NULL: {
const char *columnDecltype = sqlite3_column_decltype(cursor.stmt, idx);
if (columnDecltype != NULL && std::string("BLOB") == columnDecltype)
row.emplace_back(Encodable::Uint8List{});
else
row.emplace_back(nullptr);
break;
}
default:
break;
}
}
rows.emplace_back(row);
continue;
}
if (status == SQLITE_DONE) {
this->closeCursor(cursor);
break;
}
this->closeCursor(cursor);
return this->currentErrorMessage();
}
result = Encodable::Map{{"columns", columns}, {"rows", rows}};
if (status != SQLITE_DONE)
result.insert({ARG_CURSOR_ID, cursor.id});
return std::nullopt;
}
std::optional<std::string> Database::Batch(const std::vector<Operation> &operations,
bool continueOnError,
Encodable::List &results)
{
for (const auto &operation : operations) {
const auto &method = operation.method;
if (method == METHOD_INSERT) {
int insertID = 0;
const auto error = this->Insert(operation.sql, operation.arguments, insertID);
if (error) {
if (!continueOnError)
return error;
addError(results, *error);
continue;
}
if (insertID == 0)
addResult(results, nullptr);
else
addResult(results, insertID);
continue;
}
if (method == METHOD_EXECUTE) {
const auto error = this->Execute(operation.sql, operation.arguments);
if (error) {
if (!continueOnError)
return error;
addError(results, *error);
continue;
}
addResult(results, nullptr);
continue;
}
if (method == METHOD_QUERY) {
Encodable::Map result;
const auto error = this->Query(operation.sql, operation.arguments, result);
if (error) {
if (!continueOnError)
return error;
addError(results, *error);
continue;
}
addResult(results, result);
continue;
}
if (method == METHOD_UPDATE) {
int updated = 0;
const auto error = this->Update(operation.sql, operation.arguments, updated);
if (error) {
if (!continueOnError)
return error;
addError(results, *error);
continue;
}
addResult(results, updated);
continue;
}
}
return std::nullopt;
}

44
packages/sqflite/sqflite_aurora/aurora/lib/logger.cpp

@ -0,0 +1,44 @@
#include <flutter/logger.h>
#include <sqflite_aurora/logger.h>
Logger::Logger(Level level, const std::string &tag)
: level(level)
, tag(tag)
, devnull(0)
{}
Logger::Level Logger::LogLevel() const
{
return this->level;
}
void Logger::SetLogLevel(Level level)
{
this->level = level;
}
std::string Logger::Tag() const
{
return this->tag;
}
void Logger::SetTag(const std::string &tag)
{
this->tag = tag;
}
std::ostream &Logger::verb()
{
if (this->level >= Level::Verbose)
return loginfo << (this->tag.empty() ? "" : "[" + this->tag + "] ");
return this->devnull;
}
std::ostream &Logger::sql()
{
if (this->level >= Level::Sql)
return loginfo << (this->tag.empty() ? "" : "[" + this->tag + "] ");
return this->devnull;
}

619
packages/sqflite/sqflite_aurora/aurora/lib/sqflite_aurora_plugin.cpp

@ -0,0 +1,619 @@
#include <flutter/application.h>
#include <flutter/logger.h>
#include <sqflite_aurora/constants.h>
#include <sqflite_aurora/sqflite_aurora_plugin.h>
#include <filesystem>
#include <fstream>
namespace {
int64_t GetTransactionID(const Encodable &args)
{
if (!args.HasKey(ARG_TRANSACTION_ID))
return static_cast<int64_t>(Database::TransactionID::None);
if (args[ARG_TRANSACTION_ID].IsNull())
return static_cast<int64_t>(Database::TransactionID::None);
if (!args[ARG_TRANSACTION_ID].IsInt())
return static_cast<int64_t>(Database::TransactionID::None);
return args[ARG_TRANSACTION_ID].GetInt();
}
Encodable::List GetSqlArguments(const Encodable &args)
{
if (!args.HasKey(ARG_SQL_ARGUMENTS))
return Encodable::List{};
if (args[ARG_SQL_ARGUMENTS].IsNull())
return Encodable::List{};
if (!args[ARG_SQL_ARGUMENTS].IsList())
return Encodable::List{};
return args[ARG_SQL_ARGUMENTS].GetList();
}
} /* namespace */
SqfliteAuroraPlugin::SqfliteAuroraPlugin()
: dbID(0)
, logger(Logger::Level::None, "sqflite")
{}
void SqfliteAuroraPlugin::RegisterWithRegistrar(PluginRegistrar &registrar)
{
registrar.RegisterMethodChannel("com.tekartik.sqflite",
MethodCodecType::Standard,
[this](const MethodCall &call) { this->onMethodCall(call); });
}
void SqfliteAuroraPlugin::onMethodCall(const MethodCall &call)
{
const auto &method = call.GetMethod();
if (method == METHOD_GET_PLATFORM_VERSION) {
this->onPlatformVersionCall(call);
return;
}
if (method == METHOD_OPEN_DATABASE) {
this->onOpenDatabaseCall(call);
return;
}
if (method == METHOD_CLOSE_DATABASE) {
this->onCloseDatabaseCall(call);
return;
}
if (method == METHOD_DELETE_DATABASE) {
this->onDeleteDatabaseCall(call);
return;
}
if (method == METHOD_DATABASE_EXISTS) {
this->onDatabaseExistsCall(call);
return;
}
if (method == METHOD_GET_DATABASES_PATH) {
this->onGetDatabasesPathCall(call);
return;
}
if (method == METHOD_OPTIONS) {
this->onOptionsCall(call);
return;
}
if (method == METHOD_DEBUG) {
this->onDebugCall(call);
return;
}
if (method == METHOD_EXECUTE) {
this->onExecuteCall(call);
return;
}
if (method == METHOD_QUERY) {
this->onQueryCall(call);
return;
}
if (method == METHOD_QUERY_CURSOR_NEXT) {
this->onQueryCursorNextCall(call);
return;
}
if (method == METHOD_UPDATE) {
this->onUpdateCall(call);
return;
}
if (method == METHOD_INSERT) {
this->onInsertCall(call);
return;
}
if (method == METHOD_BATCH) {
this->onBatchCall(call);
return;
}
this->success(call);
}
void SqfliteAuroraPlugin::onPlatformVersionCall(const MethodCall &call)
{
std::ifstream in("/etc/os-release");
std::string line;
while (in.is_open() && std::getline(in, line)) {
if (line.rfind("VERSION_ID=") != 0)
continue;
this->success(call, "Aurora " + line.substr(11));
return;
}
this->success(call, "Aurora");
}
void SqfliteAuroraPlugin::onOpenDatabaseCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbPath = args[ARG_PATH].GetString();
const auto readOnly = args.HasKey(ARG_READ_ONLY) ? args[ARG_READ_ONLY].GetBoolean() : false;
const auto inMemory = dbPath.empty() || dbPath == ":memory:";
const auto singleton = args[ARG_SINGLE_INSTANCE].GetBoolean() && !inMemory;
if (singleton) {
const auto db = this->databaseByPath(dbPath);
if (db) {
if (db->IsOpen()) {
this->logger.verb() << "re-opened single instance database"
<< (db->IsInTransaction() ? "(in transaction) " : "")
<< db->ID() << " " << db->Path() << std::endl;
this->success(call, makeOpenResult(db->ID(), true, db->IsInTransaction()));
return;
}
this->logger.verb() << "single instance database " << db->Path() << " not opened"
<< std::endl;
}
}
const auto db = std::make_shared<Database>(++dbID, dbPath, singleton, logger);
this->asynq.Push([this, db, readOnly, call] {
this->logger.sql() << "open database " + db->Path() + " (ID=" << db->ID() << ")"
<< std::endl;
const auto error = readOnly ? db->OpenReadOnly() : db->Open();
if (error) {
this->error(call, ERROR_OPEN, db->Path(), *error);
return;
}
this->databaseAdd(db);
this->success(call, makeOpenResult(db->ID(), false, false));
});
}
void SqfliteAuroraPlugin::onCloseDatabaseCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbID = args[ARG_ID].GetInt();
const auto db = databaseByID(dbID);
this->asynq.Push([this, db, dbID, call] {
if (!db) {
this->error(call, ERROR_CLOSED, "database closed", "ID=" + std::to_string(dbID) + ")");
return;
}
this->logger.sql() << "closing database with ID=" << db->ID() << std::endl;
const auto error = db->Close();
if (error) {
this->error(call, ERROR_CLOSE, db->Path(), *error);
return;
}
this->databaseRemove(db);
this->success(call);
});
}
void SqfliteAuroraPlugin::onDeleteDatabaseCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbPath = args[ARG_PATH].GetString();
const auto db = databaseByPath(dbPath);
this->asynq.Push([this, db, dbPath, call] {
if (db) {
if (db->IsOpen()) {
this->logger.verb()
<< "close database " << db->Path() << " (ID=" << db->ID() << ")" << std::endl;
const auto error = db->Close();
if (error) {
this->error(call, ERROR_CLOSE, db->Path(), *error);
return;
}
}
this->databaseRemove(db);
}
if (std::filesystem::exists(dbPath)) {
this->logger.verb() << "delete not opened database " << dbPath << std::endl;
std::filesystem::remove(dbPath);
}
this->success(call);
});
}
void SqfliteAuroraPlugin::onDatabaseExistsCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbPath = args[ARG_PATH].GetString();
this->success(call, std::filesystem::exists(dbPath));
}
void SqfliteAuroraPlugin::onGetDatabasesPathCall(const MethodCall &call)
{
const auto home = std::getenv("HOME");
if (home == nullptr) {
this->error(call, ERROR_INTERNAL, "environment variable $HOME not found");
return;
}
const auto [orgname, appname] = Application::GetID();
const auto directory = std::filesystem::path(home) / ".local/share" / orgname / appname;
this->success(call, directory.generic_string());
}
void SqfliteAuroraPlugin::onOptionsCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto level = args[ARG_LOG_LEVEL].GetInt();
this->logger.SetLogLevel(static_cast<Logger::Level>(level));
this->success(call);
}
void SqfliteAuroraPlugin::onDebugCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto cmd = args[ARG_COMMAND].GetString();
std::lock_guard<std::mutex> lock(this->mutex);
Encodable::Map result;
if (cmd == "get") {
if (this->logger.LogLevel() > Logger::Level::None)
result.emplace(ARG_LOG_LEVEL, static_cast<Encodable::Int>(this->logger.LogLevel()));
if (!this->databases.empty()) {
Encodable::Map databases;
for (const auto &[id, db] : this->databases) {
Encodable::Map info;
info.emplace(ARG_PATH, db->Path());
info.emplace(ARG_SINGLE_INSTANCE, db->IsSingleInstance());
if (db->LogLevel() > Logger::Level::None)
info.emplace(ARG_LOG_LEVEL, static_cast<Encodable::Int>(db->LogLevel()));
databases.emplace(std::to_string(id), info);
}
result.emplace(ARG_DATABASES, databases);
}
}
this->success(call, result);
}
void SqfliteAuroraPlugin::onExecuteCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbID = args[ARG_ID].GetInt();
const auto sql = args[ARG_SQL].GetString();
const auto sqlArgs = GetSqlArguments(args);
const auto inTransactionChange = args.HasKey(ARG_IN_TRANSACTION)
? args[ARG_IN_TRANSACTION].GetBoolean()
: false;
const auto transactionID = GetTransactionID(args);
const auto enteringTransaction = inTransactionChange == true
&& transactionID == Database::TransactionID::None;
const auto db = databaseByID(dbID);
if (!db) {
this->error(call, ERROR_CLOSED, "database closed", "ID=" + std::to_string(dbID) + ")");
return;
}
this->asynq.Push(
[this, db, sql, sqlArgs, inTransactionChange, enteringTransaction, transactionID, call] {
db->ProcessSqlCommand(
transactionID,
[this, db, sql, sqlArgs, inTransactionChange, enteringTransaction, call] {
if (enteringTransaction)
db->EnterInTransaction();
const auto error = db->Execute(sql, sqlArgs);
if (error) {
db->LeaveTransaction();
this->error(call, ERROR_INTERNAL, *error);
return;
}
if (enteringTransaction) {
this->success(call,
Encodable::Map{
{ARG_TRANSACTION_ID, db->CurrentTransactionID()},
});
return;
}
if (inTransactionChange == false)
db->LeaveTransaction();
this->success(call);
});
});
}
void SqfliteAuroraPlugin::onQueryCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbID = args[ARG_ID].GetInt();
const auto sql = args[ARG_SQL].GetString();
const auto sqlArgs = GetSqlArguments(args);
const auto transactionID = GetTransactionID(args);
const auto pageSize = args.HasKey(ARG_CURSOR_PAGE_SIZE) ? args[ARG_CURSOR_PAGE_SIZE].GetInt()
: -1;
const auto db = databaseByID(dbID);
if (!db) {
this->error(call, ERROR_CLOSED, "database closed", "ID=" + std::to_string(dbID) + ")");
return;
}
this->asynq.Push([this, db, sql, sqlArgs, transactionID, pageSize, call] {
db->ProcessSqlCommand(transactionID, [this, db, sql, sqlArgs, pageSize, call] {
Encodable::Map result;
std::optional<std::string> error;
if (pageSize <= 0)
error = db->Query(sql, sqlArgs, result);
else
error = db->QueryWithPageSize(sql, sqlArgs, pageSize, result);
if (error) {
this->error(call, ERROR_INTERNAL, *error);
return;
}
this->success(call, result);
});
});
}
void SqfliteAuroraPlugin::onQueryCursorNextCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbID = args[ARG_ID].GetInt();
const auto cursorID = args[ARG_CURSOR_ID].GetInt();
const auto closeCursor = args.HasKey(ARG_CANCEL) ? args[ARG_CANCEL].GetBoolean() : false;
const auto transactionID = GetTransactionID(args);
const auto db = databaseByID(dbID);
if (!db) {
this->error(call, ERROR_CLOSED, "database closed", "ID=" + std::to_string(dbID) + ")");
return;
}
this->asynq.Push([this, db, cursorID, closeCursor, transactionID, call] {
db->ProcessSqlCommand(transactionID, [this, db, cursorID, closeCursor, call] {
Encodable::Map result;
const auto error = db->QueryCursorNext(cursorID, closeCursor, result);
if (error) {
this->error(call, ERROR_INTERNAL, *error);
return;
}
this->success(call, result);
});
});
}
void SqfliteAuroraPlugin::onUpdateCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbID = args[ARG_ID].GetInt();
const auto sql = args[ARG_SQL].GetString();
const auto sqlArgs = GetSqlArguments(args);
const auto transactionID = GetTransactionID(args);
const auto db = databaseByID(dbID);
if (!db) {
this->error(call, ERROR_CLOSED, "database closed", "ID=" + std::to_string(dbID) + ")");
return;
}
this->asynq.Push([this, db, sql, sqlArgs, transactionID, call] {
db->ProcessSqlCommand(transactionID, [this, db, sql, sqlArgs, call] {
int updated = 0;
const auto error = db->Update(sql, sqlArgs, updated);
if (error) {
this->error(call, ERROR_INTERNAL, *error);
return;
}
this->success(call, updated);
});
});
}
void SqfliteAuroraPlugin::onInsertCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbID = args[ARG_ID].GetInt();
const auto sql = args[ARG_SQL].GetString();
const auto sqlArgs = GetSqlArguments(args);
const auto transactionID = GetTransactionID(args);
const auto db = databaseByID(dbID);
if (!db) {
this->error(call, ERROR_CLOSED, "database closed", "ID=" + std::to_string(dbID) + ")");
return;
}
this->asynq.Push([this, db, sql, sqlArgs, transactionID, call] {
db->ProcessSqlCommand(transactionID, [this, db, sql, sqlArgs, call] {
int insertID = 0;
const auto error = db->Insert(sql, sqlArgs, insertID);
if (error) {
this->error(call, ERROR_INTERNAL, *error);
return;
}
if (insertID == 0)
this->success(call);
else
this->success(call, insertID);
});
});
}
void SqfliteAuroraPlugin::onBatchCall(const MethodCall &call)
{
const auto &args = call.GetArguments();
const auto dbID = args[ARG_ID].GetInt();
const auto &operations = args[ARG_OPERATIONS].GetList();
const auto noResult = args.HasKey(ARG_NO_RESULT) ? args[ARG_NO_RESULT].GetBoolean() : false;
const auto continueOnError = args.HasKey(ARG_CONTINUE_ON_ERROR)
? args[ARG_CONTINUE_ON_ERROR].GetBoolean()
: false;
const auto transactionID = GetTransactionID(args);
const auto db = databaseByID(dbID);
if (!db) {
this->error(call, ERROR_CLOSED, "database closed", "ID=" + std::to_string(dbID) + ")");
return;
}
std::vector<Database::Operation> dbOperations;
for (const auto &operation : operations) {
const auto method = operation[ARG_METHOD].GetString();
const auto sql = operation[ARG_SQL].GetString();
const auto sqlArgs = GetSqlArguments(operation);
dbOperations.emplace_back(Database::Operation{method, sql, sqlArgs});
}
this->asynq.Push([this, db, dbOperations, transactionID, continueOnError, noResult, call] {
const auto command = [this, db, dbOperations, continueOnError, noResult, call] {
Encodable::List results;
const auto error = db->Batch(dbOperations, continueOnError, results);
if (error) {
this->error(call, ERROR_INTERNAL, *error);
return;
}
if (noResult)
this->success(call);
else
this->success(call, results);
};
db->ProcessSqlCommand(transactionID, command);
});
}
std::shared_ptr<Database> SqfliteAuroraPlugin::databaseByPath(const std::string &path)
{
std::lock_guard<std::mutex> lock(this->mutex);
if (!this->singletonDatabases.count(path))
return nullptr;
return this->singletonDatabases.at(path);
}
std::shared_ptr<Database> SqfliteAuroraPlugin::databaseByID(int64_t id)
{
std::lock_guard<std::mutex> lock(this->mutex);
if (!this->databases.count(id))
return nullptr;
return this->databases.at(id);
}
void SqfliteAuroraPlugin::databaseRemove(std::shared_ptr<Database> db)
{
std::lock_guard<std::mutex> lock(this->mutex);
if (db->IsSingleInstance())
this->singletonDatabases.erase(db->Path());
this->databases.erase(db->ID());
}
void SqfliteAuroraPlugin::databaseAdd(std::shared_ptr<Database> db)
{
std::lock_guard<std::mutex> lock(this->mutex);
if (db->IsSingleInstance())
this->singletonDatabases.emplace(db->Path(), db);
this->databases.emplace(db->ID(), db);
}
void SqfliteAuroraPlugin::success(const MethodCall &call, const Encodable &result)
{
call.SendSuccessResponse(result);
}
void SqfliteAuroraPlugin::error(const MethodCall &call,
const std::string &error,
const std::string &message,
const std::string &desc,
const Encodable &details)
{
call.SendErrorResponse(ERROR_SQFLITE,
error + ": " + message + (desc.empty() ? "" : " (" + desc + ")"),
details);
}
Encodable::Map SqfliteAuroraPlugin::makeOpenResult(int64_t dbID,
bool recovered,
bool recoveredInTransaction)
{
Encodable::Map result = {{ARG_ID, dbID}};
if (recovered)
result.emplace(ARG_RECOVERED, true);
if (recoveredInTransaction)
result.emplace(ARG_RECOVERED_IN_TRANSACTION, true);
return result;
}

BIN
packages/sqflite/sqflite_aurora/data/preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

45
packages/sqflite/sqflite_aurora/example/.gitignore vendored

@ -0,0 +1,45 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/pubspec.lock
/android/app/debug
/android/app/profile
/android/app/release

25
packages/sqflite/sqflite_aurora/example/LICENSE

@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2019, Alexandre Roux Tekartik
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.
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 HOLDER 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.

9
packages/sqflite/sqflite_aurora/example/README.md

@ -0,0 +1,9 @@
# Sqflite example for Aurora OS
Demonstrates how to use the `sqflite_aurora` plugin.
## Building
```shell
$ flutter build aurora [--release|--debug|--profile]
```

87
packages/sqflite/sqflite_aurora/example/analysis_options.yaml

@ -0,0 +1,87 @@
include: package:flutter_lints/flutter.yaml
analyzer:
language:
strict-casts: true
strict-inference: true
errors:
missing_required_param: warning
missing_return: warning
todo: ignore
included_file_warning: ignore
linter:
rules:
- always_declare_return_types
- avoid_dynamic_calls
- avoid_empty_else
- avoid_relative_lib_imports
- avoid_shadowing_type_parameters
- avoid_slow_async_io
- avoid_types_as_parameter_names
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
- curly_braces_in_flow_control_structures
- directives_ordering
- empty_catches
- hash_and_equals
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- no_adjacent_strings_in_list
- no_duplicate_case_values
- non_constant_identifier_names
- omit_local_variable_types
- package_api_docs
- package_prefixed_library_names
- prefer_generic_function_type_aliases
- prefer_is_empty
- prefer_is_not_empty
- prefer_iterable_whereType
- prefer_single_quotes
- prefer_typing_uninitialized_variables
- sort_child_properties_last
- test_types_in_equals
- throw_in_finally
- unawaited_futures
- unnecessary_null_aware_assignments
- unnecessary_statements
- unrelated_type_equality_checks
- unsafe_html
- valid_regexps
- constant_identifier_names
- control_flow_in_finally
- empty_statements
- implementation_imports
- overridden_fields
- package_names
- prefer_const_constructors
- prefer_initializing_formals
- prefer_void_to_null
- always_require_non_null_named_parameters
- annotate_overrides
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_return_types_on_setters
- empty_constructor_bodies
- library_names
- library_prefixes
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_contains
- prefer_equal_for_default_values
- slash_for_doc_comments
- type_init_formals
- unnecessary_const
- unnecessary_new
- unnecessary_null_in_if_null_operators
- use_rethrow_when_possible
- public_member_api_docs
- sort_constructors_first
- sort_unnamed_constructors_first

BIN
packages/sqflite/sqflite_aurora/example/assets/example.db

Binary file not shown.

BIN
packages/sqflite/sqflite_aurora/example/assets/issue_64.db

Binary file not shown.

1
packages/sqflite/sqflite_aurora/example/aurora/.gitignore vendored

@ -0,0 +1 @@
flutter/ephemeral

47
packages/sqflite/sqflite_aurora/example/aurora/CMakeLists.txt

@ -0,0 +1,47 @@
cmake_minimum_required(VERSION 3.10)
project(com.example.sqflite_aurora_example LANGUAGES CXX)
include(GNUInstallDirs)
set(BINARY_NAME ${CMAKE_PROJECT_NAME})
set(FLUTTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/flutter)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_SKIP_RPATH OFF)
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../share/${BINARY_NAME}/lib")
find_package(PkgConfig REQUIRED)
pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder)
add_executable(${BINARY_NAME} main.cpp ${FLUTTER_DIR}/generated_plugin_registrant.cpp)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::FlutterEmbedder)
target_include_directories(${BINARY_NAME} PRIVATE ${FLUTTER_DIR})
include(flutter/generated_plugins.cmake)
set(PACKAGE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/${BINARY_NAME})
set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/applications)
set(ICONS_INSTALL_ROOT_DIR ${CMAKE_INSTALL_DATADIR}/icons/hicolor)
add_custom_command(TARGET ${BINARY_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libflutter-embedder.so
${PROJECT_BINARY_DIR}/bundle/lib/libflutter-embedder.so)
install(FILES ${PROJECT_BINARY_DIR}/bundle/icudtl.dat DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/flutter_assets DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/lib DESTINATION ${PACKAGE_INSTALL_DIR})
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES desktop/${BINARY_NAME}.desktop DESTINATION ${DESKTOP_INSTALL_DIR})
foreach(ICONS_SIZE 86x86 108x108 128x128 172x172)
install(FILES icons/${ICONS_SIZE}.png
RENAME ${BINARY_NAME}.png
DESTINATION ${ICONS_INSTALL_ROOT_DIR}/${ICONS_SIZE}/apps/)
endforeach(ICONS_SIZE)

12
packages/sqflite/sqflite_aurora/example/aurora/desktop/com.example.sqflite_aurora_example.desktop

@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
Name=Sqflite Example
Comment=Demonstrates how to use the sqflite_aurora plugin.
Icon=com.example.sqflite_aurora_example
Exec=/usr/bin/com.example.sqflite_aurora_example
X-Nemo-Application-Type=silica-qt5
[X-Application]
Permissions=
OrganizationName=com.example
ApplicationName=sqflite_aurora_example

16
packages/sqflite/sqflite_aurora/example/aurora/flutter/generated_plugin_registrant.cpp

@ -0,0 +1,16 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include <flutter/application.h>
#include <sqflite_aurora/sqflite_aurora_plugin.h>
#include "generated_plugin_registrant.h"
void RegisterPlugins() {
Application::RegisterPlugins({
std::make_shared<SqfliteAuroraPlugin>(),
});
}

12
packages/sqflite/sqflite_aurora/example/aurora/flutter/generated_plugin_registrant.h

@ -0,0 +1,12 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT
#define GENERATED_PLUGIN_REGISTRANT
void RegisterPlugins();
#endif /* GENERATED_PLUGIN_REGISTRANT */

31
packages/sqflite/sqflite_aurora/example/aurora/flutter/generated_plugins.cmake

@ -0,0 +1,31 @@
#
# Generated file, do not edit.
#
set(ROOT_PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}")
function(add_library TARGET)
_add_library(${TARGET} ${ARGN})
if(NOT "${TARGET}" MATCHES "^PkgConfig::.*")
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<TARGET_FILE:${TARGET}>"
"${ROOT_PROJECT_BINARY_DIR}/bundle/lib/$<TARGET_FILE_NAME:${TARGET}>")
endif(NOT "${TARGET}" MATCHES "^PkgConfig::.*")
endfunction()
list(APPEND FLUTTER_PLATFORM_PLUGIN_LIST
sqflite_aurora
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
foreach(PLUGIN ${FLUTTER_PLATFORM_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${PLUGIN}/aurora plugins/${PLUGIN})
target_link_libraries(${BINARY_NAME} PRIVATE ${PLUGIN}_platform_plugin)
endforeach(PLUGIN)
foreach(FFI_PLUGIN ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${FFI_PLUGIN}/aurora plugins/${FFI_PLUGIN})
endforeach(FFI_PLUGIN)

BIN
packages/sqflite/sqflite_aurora/example/aurora/icons/108x108.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
packages/sqflite/sqflite_aurora/example/aurora/icons/128x128.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
packages/sqflite/sqflite_aurora/example/aurora/icons/172x172.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
packages/sqflite/sqflite_aurora/example/aurora/icons/86x86.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

10
packages/sqflite/sqflite_aurora/example/aurora/main.cpp

@ -0,0 +1,10 @@
#include <flutter/application.h>
#include "generated_plugin_registrant.h"
int main(int argc, char *argv[]) {
Application::Initialize(argc, argv);
Application::SetPixelRatio(1.8);
RegisterPlugins();
Application::Launch();
return 0;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save