diff --git a/packages/shared_preferences/shared_preferences_ohos/.gitignore b/packages/shared_preferences/shared_preferences_ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6665baf5ad7de7fd7352c04cfa1b6d9e318a73c9 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages + +pubspec.lock +GeneratedPluginRegistrant* +ohos/**/oh_modules +ohos/**.har +ohos/**/BuildProfile.ets +ohos/**/oh-package-lock.json5 diff --git a/packages/shared_preferences/shared_preferences_ohos/AUTHORS b/packages/shared_preferences/shared_preferences_ohos/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..fc4d15a6a5ddfeb0896666c68ba8beaeb131932e --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/AUTHORS @@ -0,0 +1,79 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +The Chromium Authors +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/packages/shared_preferences/shared_preferences_ohos/CHANGELOG.md b/packages/shared_preferences/shared_preferences_ohos/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/packages/shared_preferences/shared_preferences_ohos/README.md b/packages/shared_preferences/shared_preferences_ohos/README.md new file mode 100644 index 0000000000000000000000000000000000000000..79f05b03295e2c33ce012ad01adfd8085a955768 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/README.md @@ -0,0 +1,15 @@ +# shared\_preferences\_ohos + +The OpenHarmony implementation of [`shared_preferences`][1]. + +## Usage + +This package is [endorsed][2], which means you can simply use `shared_preferences` +normally. This package will be automatically included in your app when you do, +so you do not need to add it to your `pubspec.yaml`. + +However, if you `import` this package to use any of its APIs directly, you +should add it to your `pubspec.yaml` as usual. + +[1]: https://pub.dev/packages/shared_preferences +[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin diff --git a/packages/shared_preferences/shared_preferences_ohos/example/.gitignore b/packages/shared_preferences/shared_preferences_ohos/example/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..273fc7b93cb91b893a172430915cee77f5937b24 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/.gitignore @@ -0,0 +1,49 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release + +entry/libs/arm64-v8a/libflutter.so +entry/src/main/resources/rawfile/flutter_assets/ diff --git a/packages/shared_preferences/shared_preferences_ohos/example/README.md b/packages/shared_preferences/shared_preferences_ohos/example/README.md new file mode 100644 index 0000000000000000000000000000000000000000..96b8bb17dbff8e7acd9a1dd59c65ff40b96e1228 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/README.md @@ -0,0 +1,9 @@ +# Platform Implementation Test App + +This is a test app for manual testing and automated integration testing +of this platform implementation. It is not intended to demonstrate actual use of +this package, since the intent is that plugin clients use the app-facing +package. + +Unless you are making changes to this implementation package, this example is +very unlikely to be relevant. diff --git a/packages/shared_preferences/shared_preferences_ohos/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_ohos/example/integration_test/shared_preferences_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ec3dfd1bc88c49b9ce842d9bcff423f54758bfa0 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/integration_test/shared_preferences_test.dart @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('SharedPreferencesOhos', () { + const Map flutterTestValues = { + 'flutter.String': 'hello world', + 'flutter.Bool': true, + 'flutter.Int': 42, + 'flutter.Double': 3.14159, + 'flutter.StringList': ['foo', 'bar'], + }; + + const Map prefixTestValues = { + 'prefix.String': 'hello world', + 'prefix.Bool': true, + 'prefix.Int': 42, + 'prefix.Double': 3.14159, + 'prefix.StringList': ['foo', 'bar'], + }; + + const Map nonPrefixTestValues = { + 'String': 'hello world', + 'Bool': true, + 'Int': 42, + 'Double': 3.14159, + 'StringList': ['foo', 'bar'], + }; + + final Map allTestValues = {}; + + allTestValues.addAll(flutterTestValues); + allTestValues.addAll(prefixTestValues); + allTestValues.addAll(nonPrefixTestValues); + + late SharedPreferencesStorePlatform preferences; + + setUp(() async { + preferences = SharedPreferencesStorePlatform.instance; + }); + + tearDown(() async { + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + }); + + testWidgets('reading', (WidgetTester _) async { + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values['String'], isNull); + expect(values['Bool'], isNull); + expect(values['Int'], isNull); + expect(values['Double'], isNull); + expect(values['StringList'], isNull); + }); + + Future addData() async { + await preferences.setValue('String', 'String', allTestValues['String']!); + await preferences.setValue('Bool', 'Bool', allTestValues['Bool']!); + await preferences.setValue('Int', 'Int', allTestValues['Int']!); + await preferences.setValue('Double', 'Double', allTestValues['Double']!); + await preferences.setValue( + 'StringList', 'StringList', allTestValues['StringList']!); + await preferences.setValue( + 'String', 'prefix.String', allTestValues['prefix.String']!); + await preferences.setValue( + 'Bool', 'prefix.Bool', allTestValues['prefix.Bool']!); + await preferences.setValue( + 'Int', 'prefix.Int', allTestValues['prefix.Int']!); + await preferences.setValue( + 'Double', 'prefix.Double', allTestValues['prefix.Double']!); + await preferences.setValue('StringList', 'prefix.StringList', + allTestValues['prefix.StringList']!); + await preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!); + await preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!); + await preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!); + await preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!); + await preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!); + } + + testWidgets('getAllWithPrefix', (WidgetTester _) async { + await Future.wait(>[ + preferences.setValue( + 'String', 'prefix.String', allTestValues['prefix.String']!), + preferences.setValue( + 'Bool', 'prefix.Bool', allTestValues['prefix.Bool']!), + preferences.setValue('Int', 'prefix.Int', allTestValues['prefix.Int']!), + preferences.setValue( + 'Double', 'prefix.Double', allTestValues['prefix.Double']!), + preferences.setValue('StringList', 'prefix.StringList', + allTestValues['prefix.StringList']!), + preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!), + preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!), + preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!), + preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!), + preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!) + ]); + final Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix('prefix.'); + expect(values['prefix.String'], allTestValues['prefix.String']); + expect(values['prefix.Bool'], allTestValues['prefix.Bool']); + expect(values['prefix.Int'], allTestValues['prefix.Int']); + expect(values['prefix.Double'], allTestValues['prefix.Double']); + expect(values['prefix.StringList'], allTestValues['prefix.StringList']); + }); + + group('withPrefix', () { + testWidgets('clearWithPrefix', (WidgetTester _) async { + await Future.wait(>[ + preferences.setValue( + 'String', 'prefix.String', allTestValues['prefix.String']!), + preferences.setValue( + 'Bool', 'prefix.Bool', allTestValues['prefix.Bool']!), + preferences.setValue( + 'Int', 'prefix.Int', allTestValues['prefix.Int']!), + preferences.setValue( + 'Double', 'prefix.Double', allTestValues['prefix.Double']!), + preferences.setValue('StringList', 'prefix.StringList', + allTestValues['prefix.StringList']!), + preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!), + preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!), + preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!), + preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!), + preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!) + ]); + // ignore: deprecated_member_use + await preferences.clearWithPrefix('prefix.'); + Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix('prefix.'); + expect(values['prefix.String'], null); + expect(values['prefix.Bool'], null); + expect(values['prefix.Int'], null); + expect(values['prefix.Double'], null); + expect(values['prefix.StringList'], null); + // ignore: deprecated_member_use + values = await preferences.getAllWithPrefix('flutter.'); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect( + values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('getAllWithNoPrefix', (WidgetTester _) async { + await Future.wait(>[ + preferences.setValue('String', 'String', allTestValues['String']!), + preferences.setValue('Bool', 'Bool', allTestValues['Bool']!), + preferences.setValue('Int', 'Int', allTestValues['Int']!), + preferences.setValue('Double', 'Double', allTestValues['Double']!), + preferences.setValue( + 'StringList', 'StringList', allTestValues['StringList']!), + preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!), + preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!), + preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!), + preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!), + preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!) + ]); + final Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix(''); + expect(values['String'], allTestValues['String']); + expect(values['Bool'], allTestValues['Bool']); + expect(values['Int'], allTestValues['Int']); + expect(values['Double'], allTestValues['Double']); + expect(values['StringList'], allTestValues['StringList']); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect( + values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithNoPrefix', (WidgetTester _) async { + await Future.wait(>[ + preferences.setValue('String', 'String', allTestValues['String']!), + preferences.setValue('Bool', 'Bool', allTestValues['Bool']!), + preferences.setValue('Int', 'Int', allTestValues['Int']!), + preferences.setValue('Double', 'Double', allTestValues['Double']!), + preferences.setValue( + 'StringList', 'StringList', allTestValues['StringList']!), + preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!), + preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!), + preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!), + preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!), + preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!) + ]); + // ignore: deprecated_member_use + await preferences.clearWithPrefix(''); + final Map values = + // ignore: deprecated_member_use + await preferences.getAllWithPrefix(''); + expect(values['String'], null); + expect(values['Bool'], null); + expect(values['Int'], null); + expect(values['Double'], null); + expect(values['StringList'], null); + expect(values['flutter.String'], null); + expect(values['flutter.Bool'], null); + expect(values['flutter.Int'], null); + expect(values['flutter.Double'], null); + expect(values['flutter.StringList'], null); + }); + }); + + testWidgets('get all with prefix', (WidgetTester _) async { + await addData(); + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(values['prefix.String'], allTestValues['prefix.String']); + expect(values['prefix.Bool'], allTestValues['prefix.Bool']); + expect(values['prefix.Int'], allTestValues['prefix.Int']); + expect(values['prefix.Double'], allTestValues['prefix.Double']); + expect(values['prefix.StringList'], allTestValues['prefix.StringList']); + }); + + testWidgets('get all with allow list', (WidgetTester _) async { + await addData(); + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter( + prefix: 'prefix.', + allowList: {'prefix.String'}, + ), + ), + ); + expect(values['prefix.String'], allTestValues['prefix.String']); + expect(values['prefix.Bool'], null); + expect(values['prefix.Int'], null); + expect(values['prefix.Double'], null); + expect(values['prefix.StringList'], null); + }); + + testWidgets('getAllWithNoPrefix', (WidgetTester _) async { + await addData(); + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values['String'], allTestValues['String']); + expect(values['Bool'], allTestValues['Bool']); + expect(values['Int'], allTestValues['Int']); + expect(values['Double'], allTestValues['Double']); + expect(values['StringList'], allTestValues['StringList']); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithParameters', (WidgetTester _) async { + await addData(); + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(values['prefix.String'], null); + expect(values['prefix.Bool'], null); + expect(values['prefix.Int'], null); + expect(values['prefix.Double'], null); + expect(values['prefix.StringList'], null); + values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'flutter.'), + ), + ); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithParameters with allow list', (WidgetTester _) async { + await addData(); + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter( + prefix: 'prefix.', + allowList: { + 'prefix.Double', + 'prefix.Int', + 'prefix.Bool', + 'prefix.String', + }, + ), + ), + ); + Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(values['prefix.String'], null); + expect(values['prefix.Bool'], null); + expect(values['prefix.Int'], null); + expect(values['prefix.Double'], null); + expect(values['prefix.StringList'], allTestValues['prefix.StringList']); + values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'flutter.'), + ), + ); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('clearWithNoPrefix', (WidgetTester _) async { + await addData(); + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values['String'], null); + expect(values['Bool'], null); + expect(values['Int'], null); + expect(values['Double'], null); + expect(values['StringList'], null); + expect(values['flutter.String'], null); + expect(values['flutter.Bool'], null); + expect(values['flutter.Int'], null); + expect(values['flutter.Double'], null); + expect(values['flutter.StringList'], null); + }); + + testWidgets('getAll', (WidgetTester _) async { + await preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!); + await preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!); + await preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!); + await preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!); + await preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!); + final Map values = await preferences.getAll(); + expect(values['flutter.String'], allTestValues['flutter.String']); + expect(values['flutter.Bool'], allTestValues['flutter.Bool']); + expect(values['flutter.Int'], allTestValues['flutter.Int']); + expect(values['flutter.Double'], allTestValues['flutter.Double']); + expect(values['flutter.StringList'], allTestValues['flutter.StringList']); + }); + + testWidgets('remove', (WidgetTester _) async { + const String key = 'testKey'; + await preferences.setValue( + 'String', key, allTestValues['flutter.String']!); + await preferences.setValue('Bool', key, allTestValues['flutter.Bool']!); + await preferences.setValue('Int', key, allTestValues['flutter.Int']!); + await preferences.setValue( + 'Double', key, allTestValues['flutter.Double']!); + await preferences.setValue( + 'StringList', key, allTestValues['flutter.StringList']!); + await preferences.remove(key); + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values[key], isNull); + }); + + testWidgets('clear', (WidgetTester _) async { + await preferences.setValue( + 'String', 'flutter.String', allTestValues['flutter.String']!); + await preferences.setValue( + 'Bool', 'flutter.Bool', allTestValues['flutter.Bool']!); + await preferences.setValue( + 'Int', 'flutter.Int', allTestValues['flutter.Int']!); + await preferences.setValue( + 'Double', 'flutter.Double', allTestValues['flutter.Double']!); + await preferences.setValue('StringList', 'flutter.StringList', + allTestValues['flutter.StringList']!); + await preferences.clear(); + final Map values = await preferences.getAll(); + expect(values['flutter.String'], null); + expect(values['flutter.Bool'], null); + expect(values['flutter.Int'], null); + expect(values['flutter.Double'], null); + expect(values['flutter.StringList'], null); + }); + + testWidgets('simultaneous writes', (WidgetTester _) async { + final List> writes = >[]; + const int writeCount = 100; + for (int i = 1; i <= writeCount; i++) { + writes.add(preferences.setValue('Int', 'Int', i)); + } + final List result = await Future.wait(writes, eagerError: true); + // All writes should succeed. + expect(result.where((bool element) => !element), isEmpty); + // The last write should win. + final Map values = await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values['Int'], writeCount); + }); + + testWidgets('string clash with lists, big integers and doubles', + (WidgetTester _) async { + const String key = 'akey'; + const String value = 'a string value'; + await preferences.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + + // Special prefixes used to store datatypes that can't be stored directly + // in SharedPreferences as strings instead. + const List specialPrefixes = [ + // Prefix for lists: + 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu', + // Prefix for big integers: + 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBCaWdJbnRlZ2Vy', + // Prefix for doubles: + 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBEb3VibGUu', + ]; + for (final String prefix in specialPrefixes) { + expect(preferences.setValue('String', key, prefix + value), + throwsA(isA())); + final Map values = + await preferences.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(values[key], null); + } + }); + }); +} diff --git a/packages/shared_preferences/shared_preferences_ohos/example/lib/main.dart b/packages/shared_preferences/shared_preferences_ohos/example/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..3b7dbce46452516191ce591eec20bcee31720170 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/lib/main.dart @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ignore_for_file: public_member_api_docs + +import 'package:flutter/material.dart'; +import 'package:shared_preferences_ohos/shared_preferences_ohos.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return const MaterialApp( + title: 'SharedPreferences Demo', + home: SharedPreferencesDemo(), + ); + } +} + +class SharedPreferencesDemo extends StatefulWidget { + const SharedPreferencesDemo({super.key}); + + @override + SharedPreferencesDemoState createState() => SharedPreferencesDemoState(); +} + +class SharedPreferencesDemoState extends State { + final SharedPreferencesStorePlatform _prefs = + SharedPreferencesOhos(); + late Future _counter; + + // Includes the prefix because this is using the platform interface directly, + // but the prefix (which the native code assumes is present) is added by the + // app-facing package. + static const String _prefKey = 'flutter.counter'; + + Future _incrementCounter() async { + final Map values = await _prefs.getAll(); + final int counter = ((values[_prefKey] as int?) ?? 0) + 1; + + setState(() { + _counter = _prefs.setValue('Int', _prefKey, counter).then((bool success) { + return counter; + }); + }); + } + + @override + void initState() { + super.initState(); + _counter = _prefs.getAll().then((Map values) { + return (values[_prefKey] as int?) ?? 0; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('SharedPreferences Demo'), + ), + body: Center( + child: FutureBuilder( + future: _counter, + builder: (BuildContext context, AsyncSnapshot snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.none: + case ConnectionState.waiting: + return const CircularProgressIndicator(); + case ConnectionState.active: + case ConnectionState.done: + if (snapshot.hasError) { + return Text('Error: ${snapshot.error}'); + } else { + return Text( + 'Button tapped ${snapshot.data} time${snapshot.data == 1 ? '' : 's'}.\n\n' + 'This should persist across restarts.', + ); + } + } + })), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), + ); + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/.gitignore b/packages/shared_preferences/shared_preferences_ohos/example/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a74246bc614d9b28a2679c43944d80730c03f6b7 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/.gitignore @@ -0,0 +1,13 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +*.har +oh-package-lock.json5 diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/app.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c6c3a46519a0ada74bc89f6e19b198c98ce2c646 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "dev.flutter.packages.file_selector_ohos_example", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/resources/base/element/string.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..35f3094bd89180cff2e12a51cb0799b4e130e5f7 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "FileSelectorOhosExample" + } + ] +} diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/resources/base/media/app_icon.png b/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/packages/shared_preferences/shared_preferences_ohos/example/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/build-profile.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..88d455f756e75de17c795e3f10e6840ff8aebf71 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/build-profile.json5 @@ -0,0 +1,36 @@ +{ + "app": { + "signingConfigs": [ + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS" + } + ], + "buildModeSet": [ + { + "name": "debug" + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/.gitignore b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8d809e9e219ea72f35798bb34318a666a6f683a4 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/.gitignore @@ -0,0 +1,8 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test +src/main/resources/rawfile/flutter_assets +oh-package-lock.json5 diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/build-profile.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4fee05f0045cc1ce1d18b7658dabfddc25c29022 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/build-profile.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/hvigorfile.ts b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..80e4ec5b81689f238c34614b167a0b9e9c83e8d9 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/libs/arm64-v8a/libc++_shared.so b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/oh-package.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..ab6a37b8361ad56a8e1e0ac4c606d4e1f6a4365e --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/oh-package.json5 @@ -0,0 +1,14 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter.har", + "integration_test": "file:../har/integration_test.har", + "shared_preferences_ohos": "file:../har/shared_preferences_ohos.har" + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..483d8221a8cd571c048ec6eba973cd0a97d8cfb9 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' +import { FlutterPlugin } from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant'; +import List from '@ohos.util.List'; +import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine'; + +export default class EntryAbility extends FlutterAbility { + configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/ets/pages/Index.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..1125f9fdd95f4310a182c1c9e3680f37f73686c9 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +let storage = LocalStorage.getShared() +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry(storage) +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + @LocalStorageLink('viewId') viewId: string = ""; + + build() { + Column() { + FlutterPage({ viewId: this.viewId }) + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/module.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b7b8f025dc5750912da86699a957fba336c362c0 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/module.json5 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/element/color.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/element/string.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/media/icon.png b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/en_US/element/string.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..7d3c2f1b51d74c9b77cd541df2a5db747a30c1d5 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..e234ecdeb68972cbec9b06614a498009d689540d --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..5725ed314a955468b9ed704b57d4013b72249c88 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + +export default class TestAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..4976263a5179927d72bca9f6168513f116a49e8a --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..040a3d0778ec7d7f9bbb28e55495ab37b6f31169 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/module.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..93136368ed44413922ac6e9fb3f382012819a35f --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/test/List.test.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..4340a28079c38279905241323020c76addf12f1f --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/test/List.test.ets @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest() +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/test/LocalUnit.test.ets b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..56331147662f5540114a4afa9cee1b8470eb0505 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/hvigor/hvigor-config.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7b7a22c8b53087b294218a9533b2a23239457c12 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,8 @@ +{ + "modelVersion": "5.0.0", + "dependencies": { + }, + 'properties': { + 'ohos.nativeResolver': false + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/hvigorfile.ts b/packages/shared_preferences/shared_preferences_ohos/example/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..6478186902c0c1ad7c966a929c7d6b7d8ae7a9f3 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/ohos/oh-package.json5 b/packages/shared_preferences/shared_preferences_ohos/example/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..34f6ef0c7387a0ab25341577429a8a670df227a7 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/ohos/oh-package.json5 @@ -0,0 +1,21 @@ +{ + "modelVersion": "5.0.0", + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "myapplication", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:./har/flutter.har" + }, + "overrides": { + "@ohos/flutter_ohos": "file:./har/flutter.har", + "integration_test": "file:./har/integration_test.har", + "@ohos/flutter_module": "file:./entry", + "shared_preferences_ohos": "file:./har/shared_preferences_ohos.har" + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_ohos/example/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8c2b2ad3b1c4e88c76250af32f71af2445326ffe --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/pubspec.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +name: shared_preferences_example +description: Demonstrates how to use the shared_preferences plugin. +publish_to: none + +environment: + sdk: ^3.4.0 + flutter: ">=3.19.0" + +dependencies: + flutter: + sdk: flutter + shared_preferences_ohos: + # When depending on this package from a real application you should use: + # shared_preferences_ohos: ^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: ../ + shared_preferences_platform_interface: ^2.4.0 + +dev_dependencies: + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/packages/shared_preferences/shared_preferences_ohos/example/test_driver/integration_test.dart b/packages/shared_preferences/shared_preferences_ohos/example/test_driver/integration_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c20ad8aee123a1893e742c989cdb70daae37cd6a --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/example/test_driver/integration_test.dart @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/packages/shared_preferences/shared_preferences_ohos/lib/shared_preferences_ohos.dart b/packages/shared_preferences/shared_preferences_ohos/lib/shared_preferences_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..4841c314aae69180a61c7936a9f5f79caf1a16de --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/lib/shared_preferences_ohos.dart @@ -0,0 +1,6 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export 'src/shared_preferences_ohos.dart'; +export 'src/shared_preferences_async_ohos.dart'; \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/lib/src/messages.g.dart b/packages/shared_preferences/shared_preferences_ohos/lib/src/messages.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..5e42d19b999df36dd208f87e9a7fbba74fb0fcc3 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/lib/src/messages.g.dart @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +class SharedPreferencesApi { + /// Constructor for [SharedPreferencesApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + SharedPreferencesApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + /// Removes property from shared preferences data set. + Future remove(String arg_key) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.remove', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_key]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } + + /// Adds property to shared preferences data set of type bool. + Future setBool(String arg_key, bool arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setBool', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_key, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } + + /// Adds property to shared preferences data set of type String. + Future setString(String arg_key, String arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setString', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_key, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } + + /// Adds property to shared preferences data set of type int. + Future setInt(String arg_key, int arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setInt', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_key, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } + + /// Adds property to shared preferences data set of type double. + Future setDouble(String arg_key, double arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setDouble', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_key, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } + + /// Adds property to shared preferences data set of type List. + Future setStringList(String arg_key, List arg_value) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setStringList', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_key, arg_value]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } + + /// Removes all properties from shared preferences data set with matching prefix. + Future clear(String arg_prefix, List? arg_allowList) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.clear', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel + .send([arg_prefix, arg_allowList]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as bool?)!; + } + } + + /// Gets all properties from shared preferences data set with matching prefix. + Future> getAll( + String arg_prefix, List? arg_allowList) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.getAll', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel + .send([arg_prefix, arg_allowList]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as Map?)!.cast(); + } + } +} diff --git a/packages/shared_preferences/shared_preferences_ohos/lib/src/messages_async.g.dart b/packages/shared_preferences/shared_preferences_ohos/lib/src/messages_async.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..0aec5f44729b5066ff9f51e697dd33827504e5cc --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/lib/src/messages_async.g.dart @@ -0,0 +1,424 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v16.0.5), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +class SharedPreferencesPigeonOptions { + SharedPreferencesPigeonOptions({ + this.fileKey, + }); + + String? fileKey; + + Object encode() { + return [ + fileKey, + ]; + } + + static SharedPreferencesPigeonOptions decode(Object result) { + result as List; + return SharedPreferencesPigeonOptions( + fileKey: result[0] as String?, + ); + } +} + +class _SharedPreferencesAsyncApiCodec extends StandardMessageCodec { + const _SharedPreferencesAsyncApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is SharedPreferencesPigeonOptions) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return SharedPreferencesPigeonOptions.decode(readValue(buffer)!); + default: + return super.readValueOfType(type, buffer); + } + } +} + +class SharedPreferencesAsyncApi { + /// Constructor for [SharedPreferencesAsyncApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + SharedPreferencesAsyncApi({BinaryMessenger? binaryMessenger}) + : __pigeon_binaryMessenger = binaryMessenger; + final BinaryMessenger? __pigeon_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = + _SharedPreferencesAsyncApiCodec(); + + /// Adds property to shared preferences data set of type bool. + Future setBool( + String key, bool value, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.setBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Adds property to shared preferences data set of type String. + Future setString( + String key, String value, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.setString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Adds property to shared preferences data set of type int. + Future setInt( + String key, int value, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.setInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Adds property to shared preferences data set of type double. + Future setDouble( + String key, double value, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.setDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Adds property to shared preferences data set of type List. + Future setStringList(String key, List value, + SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.setStringList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([key, value, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Gets individual String value stored with [key], if any. + Future getString( + String key, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.getString'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as String?); + } + } + + /// Gets individual void value stored with [key], if any. + Future getBool( + String key, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.getBool'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as bool?); + } + } + + /// Gets individual double value stored with [key], if any. + Future getDouble( + String key, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.getDouble'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as double?); + } + } + + /// Gets individual int value stored with [key], if any. + Future getInt( + String key, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.getInt'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as int?); + } + } + + /// Gets individual List value stored with [key], if any. + Future?> getStringList( + String key, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.getStringList'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = + await __pigeon_channel.send([key, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return (__pigeon_replyList[0] as List?)?.cast(); + } + } + + /// Removes all properties from shared preferences data set with matching prefix. + Future clear( + List? allowList, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.clear'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([allowList, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else { + return; + } + } + + /// Gets all properties from shared preferences data set with matching prefix. + Future> getAll( + List? allowList, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.getAll'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([allowList, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as Map?)! + .cast(); + } + } + + /// Gets all properties from shared preferences data set with matching prefix. + Future> getKeys( + List? allowList, SharedPreferencesPigeonOptions options) async { + const String __pigeon_channelName = + 'dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesAsyncApi.getKeys'; + final BasicMessageChannel __pigeon_channel = + BasicMessageChannel( + __pigeon_channelName, + pigeonChannelCodec, + binaryMessenger: __pigeon_binaryMessenger, + ); + final List? __pigeon_replyList = await __pigeon_channel + .send([allowList, options]) as List?; + if (__pigeon_replyList == null) { + throw _createConnectionError(__pigeon_channelName); + } else if (__pigeon_replyList.length > 1) { + throw PlatformException( + code: __pigeon_replyList[0]! as String, + message: __pigeon_replyList[1] as String?, + details: __pigeon_replyList[2], + ); + } else if (__pigeon_replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (__pigeon_replyList[0] as List?)!.cast(); + } + } +} diff --git a/packages/shared_preferences/shared_preferences_ohos/lib/src/shared_preferences_async_ohos.dart b/packages/shared_preferences/shared_preferences_ohos/lib/src/shared_preferences_async_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..a48db18b298a43370d7e847af420a1aea0f9e761 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/lib/src/shared_preferences_async_ohos.dart @@ -0,0 +1,195 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +import 'messages_async.g.dart'; + +const String _listPrefix = 'VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu'; + +/// The Ohos implementation of [SharedPreferencesAsyncPlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for Ohos. +base class SharedPreferencesAsyncOhos + extends SharedPreferencesAsyncPlatform { + /// Creates a new plugin implementation instance. + SharedPreferencesAsyncOhos({ + @visibleForTesting SharedPreferencesAsyncApi? api, + }) : _api = api ?? SharedPreferencesAsyncApi(); + + final SharedPreferencesAsyncApi _api; + + /// Registers this class as the default instance of [SharedPreferencesAsyncPlatform]. + static void registerWith() { + SharedPreferencesAsyncPlatform.instance = SharedPreferencesAsyncOhos(); + } + + /// Returns a SharedPreferencesPigeonOptions for sending to platform. + SharedPreferencesPigeonOptions _convertOptionsToPigeonOptions( + SharedPreferencesOptions options) { + return SharedPreferencesPigeonOptions(); + } + + @override + Future> getKeys( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + // TODO(tarrinneal): Remove cast once https://github.com/flutter/flutter/issues/97848 + // is fixed. In practice, the values will never be null, and the native implementation assumes that. + return (await _api.getKeys( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + )) + .cast() + .toSet(); + } + + @override + Future setString( + String key, + String value, + SharedPreferencesOptions options, + ) async { + if (value.startsWith(_listPrefix)) { + throw ArgumentError( + 'StorageError: This string cannot be stored as it clashes with special identifier prefixes'); + } + + return _api.setString(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setInt( + String key, + int value, + SharedPreferencesOptions options, + ) async { + return _api.setInt(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setDouble( + String key, + double value, + SharedPreferencesOptions options, + ) async { + return _api.setDouble(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setBool( + String key, + bool value, + SharedPreferencesOptions options, + ) async { + return _api.setBool(key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future setStringList( + String key, + List value, + SharedPreferencesOptions options, + ) async { + return _api.setStringList( + key, value, _convertOptionsToPigeonOptions(options)); + } + + @override + Future getString( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => + _api.getString(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future getBool( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions( + () async => _api.getBool(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future getDouble( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions(() async => + _api.getDouble(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future getInt( + String key, + SharedPreferencesOptions options, + ) async { + return _convertKnownExceptions( + () async => _api.getInt(key, _convertOptionsToPigeonOptions(options))); + } + + @override + Future?> getStringList( + String key, + SharedPreferencesOptions options, + ) async { + // TODO(tarrinneal): Remove cast once https://github.com/flutter/flutter/issues/97848 + // is fixed. In practice, the values will never be null, and the native implementation assumes that. + return _convertKnownExceptions>(() async => + (await _api.getStringList(key, _convertOptionsToPigeonOptions(options))) + ?.cast()); + } + + Future _convertKnownExceptions(Future Function() method) async { + try { + final T? value = await method(); + return value; + } on PlatformException catch (e) { + if (e.code == 'ClassCastException') { + throw TypeError(); + } else { + rethrow; + } + } + } + + @override + Future clear( + ClearPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + return _api.clear( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + ); + } + + @override + Future> getPreferences( + GetPreferencesParameters parameters, + SharedPreferencesOptions options, + ) async { + final PreferencesFilters filter = parameters.filter; + final Map data = await _api.getAll( + filter.allowList?.toList(), + _convertOptionsToPigeonOptions(options), + ); + return data.cast(); + } +} + +/// Options for the Ohos specific SharedPreferences plugin. +class SharedPreferencesAsyncOhosOptions extends SharedPreferencesOptions { + /// Constructor for SharedPreferencesAsyncOhosOptions. + const SharedPreferencesAsyncOhosOptions(); +} diff --git a/packages/shared_preferences/shared_preferences_ohos/lib/src/shared_preferences_ohos.dart b/packages/shared_preferences/shared_preferences_ohos/lib/src/shared_preferences_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..08eef116fca6818f3e7adbb40a9ccd212b399958 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/lib/src/shared_preferences_ohos.dart @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +import 'messages.g.dart'; + +/// The Ohos implementation of [SharedPreferencesStorePlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for Ohos. +class SharedPreferencesOhos extends SharedPreferencesStorePlatform { + /// Creates a new plugin implementation instance. + SharedPreferencesOhos({ + @visibleForTesting SharedPreferencesApi? api, + }) : _api = api ?? SharedPreferencesApi(); + + final SharedPreferencesApi _api; + + /// Registers this class as the default instance of [SharedPreferencesStorePlatform]. + static void registerWith() { + SharedPreferencesStorePlatform.instance = SharedPreferencesOhos(); + } + + static const String _defaultPrefix = 'flutter.'; + static const String _doublePrefix = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGRvdWJsZS4"; + + @override + Future remove(String key) async { + return _api.remove(key); + } + + @override + Future setValue(String valueType, String key, Object value) async { + switch (valueType) { + case 'String': + if((value as String).startsWith(_doublePrefix)) { + throw PlatformException( + code: 'InvalidOperation', + message: 'StorageError: This string cannot be stored as it clashes with special identifier prefixes'); + } + 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.setString(key, "$_doublePrefix$value"); + case 'StringList': + return _api.setStringList(key, value as List); + } + // TODO(tarrinneal): change to ArgumentError across all platforms. + throw PlatformException( + code: 'InvalidOperation', + message: '"$valueType" is not a supported type.'); + } + + @override + Future clear() async { + return clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: _defaultPrefix), + ), + ); + } + + @override + Future clearWithPrefix(String prefix) async { + return clearWithParameters( + ClearParameters(filter: PreferencesFilter(prefix: prefix))); + } + + @override + Future clearWithParameters(ClearParameters parameters) async { + final PreferencesFilter filter = parameters.filter; + return _api.clear( + filter.prefix, + filter.allowList?.toList(), + ); + } + + @override + Future> getAll() async { + return getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: _defaultPrefix), + ), + ); + } + + @override + Future> getAllWithPrefix(String prefix) async { + return getAllWithParameters( + GetAllParameters(filter: PreferencesFilter(prefix: prefix))); + } + + @override + Future> getAllWithParameters( + GetAllParameters parameters) async { + final PreferencesFilter filter = parameters.filter; + Map data = + await _api.getAll(filter.prefix, filter.allowList?.toList()); + data = data.map((key, value) { + if(value is String && value.startsWith(_doublePrefix)) { + return MapEntry(key, double.tryParse(value.substring(_doublePrefix.length))); + } + return MapEntry(key, value); + }); + return data.cast(); + } +} diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/.gitignore b/packages/shared_preferences/shared_preferences_ohos/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6f7b4f89c49a6abadc383d9665d3b4c171d466bc --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/.gitignore @@ -0,0 +1,17 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test + +/entry/libs/arm64-v8a/libflutter.so +/entry/src/main/resources/rawfile/flutter_assets +**.har +**/oh-package-lock.json5 +BuildProfile.ets diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/build-profile.json5 b/packages/shared_preferences/shared_preferences_ohos/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..709ca0996be0c66b59effa6a0b94f6116a5ce5be --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/build-profile.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} + diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/hvigorfile.ts b/packages/shared_preferences/shared_preferences_ohos/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..d1a91468a73f05396b9e08abaabfe8717b73fbb4 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/index.ets b/packages/shared_preferences/shared_preferences_ohos/ohos/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..ae69b1595163cef7b343ab09f674ee97b75b4fae --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/index.ets @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import SharedPreferencesOhosPlugin from './src/main/ets/shared_preferences/SharedPreferencesOhosPlugin'; +export default SharedPreferencesOhosPlugin; \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/oh-package.json5 b/packages/shared_preferences/shared_preferences_ohos/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..aff6d56c35c13c49f4da5b86b5326b7b26de1eb4 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/oh-package.json5 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "name": "shared_preferences_ohos", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "index.ets", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@ohos/flutter_ohos": "file:libs/flutter.har", + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/Messages.ets b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..10056a55c3fbece7d0bceeb5350f1902ad1bdd84 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/Messages.ets @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; + +class FlutterError extends Error { + /** The error code. */ + public code: string; + + /** The error details. Must be a datatype supported by the api codec. */ + public details: Object; + + constructor(code: string, message: string, details: Object) { + super(message); + this.code = code; + this.details = details; + } +} + +export function wrapError(exception: Error): Array { + let errorList = new Array(); + if (exception instanceof FlutterError) { + let error = exception as FlutterError; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.toString()); + errorList.push(exception.name); + errorList.push( + "Cause: " + exception.message + ", Stacktrace: " + exception.stack); + } + return errorList; +} + +export interface SharedPreferencesApi { + /** Removes property from shared preferences data set. */ + remove(key: string): boolean; + + /** Adds property to shared preferences data set of type boolean. */ + setBool(key: string, value: boolean): Promise; + + /** Adds property to shared preferences data set of type string. */ + setString(key: string, value: string): Promise; + + /** Adds property to shared preferences data set of type int. */ + setInt(key: string, value: number): Promise; + + /** Adds property to shared preferences data set of type double. */ + setDouble(key: string, value: number): Promise; + + /** Adds property to shared preferences data set of type String. */ + setStringList(key: string, value: Array): Promise; + + /** Removes all properties from shared preferences data set with matching prefix. */ + clear(prefix: string, allowList: Array): Promise; + + /** Gets all properties from shared preferences data set with matching prefix. */ + getAll(prefix: string, allowList: Array): Promise; + + /** The codec used by SharedPreferencesApi. */ + getCodec(): MessageCodec; + + /** + * Sets up an instance of `SharedPreferencesApi` to handle messages through the + * `binaryMessenger`. + */ + setup(messenger: BinaryMessenger, api: SharedPreferencesApi): void; +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/SharedPreferencesListEncoder.ets b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/SharedPreferencesListEncoder.ets new file mode 100644 index 0000000000000000000000000000000000000000..963521370207a4f6c49c0e7ca0c16767c61133f2 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/SharedPreferencesListEncoder.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * An interface used to provide conversion logic between Array and string for + * SharedPreferencesPlugin. + */ +export interface SharedPreferencesListEncoder { + /** Converts list to String for storing in shared preferences. */ + encode(list: Array): string; + /** Converts stored String representing List to List. */ + decode(listString: string): ESObject; +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/SharedPreferencesOhosPlugin.ets b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/SharedPreferencesOhosPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..01829a2ccf3a24d4b638b33aead0a9486af950ab --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/ets/shared_preferences/SharedPreferencesOhosPlugin.ets @@ -0,0 +1,441 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + FlutterPlugin, + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; +import { SharedPreferencesApi, wrapError } from './Messages'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import data_preferences from '@ohos.data.preferences' +import BasicMessageChannel, { Reply } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { SharedPreferencesListEncoder } from './SharedPreferencesListEncoder'; +import buffer from '@ohos.buffer'; + +const TAG = "SharedPreferencesOhosPlugin" +const PREFERENCES_NAME = "FlutterSharedPreferences"; +const LIST_IDENTIFIER = "VGhpcyBpcyB0aGUgcHJlZml4IGZvciBhIGxpc3Qu"; + +export default class SharedPreferencesOhosPlugin implements FlutterPlugin, SharedPreferencesApi { + + private preferences: data_preferences.Preferences | null = null; + private listEncoder: ListEncoder; + + getUniqueClassName(): string { + return "SharedPreferencesOhosPlugin" + } + + constructor() { + this.listEncoder = new ListEncoder(); + } + + setup(binaryMessenger: BinaryMessenger, api: SharedPreferencesApi | null): void { + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.remove", this.getCodec()); + Log.d(TAG, 'setup') + if (api != null) { + Log.d(TAG, 'setMessageHandler') + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + let wrapped = new Array(); + let args = msg as Array; + let keyArg = args[0] as string; + try { + let output = api.remove(keyArg); + wrapped.push(output); + } catch (err) { + let errs = wrapError(err); + wrapped = errs; + } + reply.reply(wrapped) + } + }); + } else { + channel.setMessageHandler(null) + } + } + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.getAll", this.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + Log.d(TAG, 'onMessage reply:' + reply) + let wrapped = new Array(); + let args = msg as Array; + let prefixArg = args[0] as string; + let allowListArg = args[1] as Array; + api.getAll(prefixArg, allowListArg).then((res) => { + wrapped.push(res); + Log.w(TAG, "getAll res=" + JSON.stringify(res)); + reply.reply(wrapped) + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to getAll. code =" + err.code +", message =" + err.message); + let errs = wrapError(err); + wrapped = errs; + reply.reply(wrapped) + }) + } + }); + } else { + channel.setMessageHandler(null) + } + } + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.clear", this.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + Log.d(TAG, 'onMessage reply:' + reply) + let wrapped = new Array(); + let args = msg as Array; + let prefixArg = args[0] as string; + let allowListArg = args[1] as Array; + api.clear(prefixArg, allowListArg).then(() => { + wrapped.push(true); + reply.reply(wrapped) + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to clear. code =" + err.code +", message =" + err.message); + let errs = wrapError(err); + wrapped = errs; + reply.reply(wrapped) + }) + } + }); + } else { + channel.setMessageHandler(null) + } + } + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setInt", this.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + let wrapped = new Array(); + let args = msg as Array; + let keyArg = args[0] as string; + let valueArg = args[1] as number; + api.setInt(keyArg, valueArg).then(() => { + wrapped.push(true); + reply.reply(wrapped) + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to setInt. code =" + err.code +", message =" + err.message); + let errs = wrapError(err); + wrapped = errs; + reply.reply(wrapped) + }) + } + }); + } else { + channel.setMessageHandler(null) + } + } + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setString", this.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + let wrapped = new Array(); + let args = msg as Array; + let keyArg = args[0] as string; + let valueArg = args[1] as string; + api.setString(keyArg, valueArg).then(() => { + wrapped.push(true); + reply.reply(wrapped) + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to setString. code =" + err.code +", message =" + err.message); + let errs = wrapError(err); + wrapped = errs; + reply.reply(wrapped) + }) + } + }); + } else { + channel.setMessageHandler(null) + } + } + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setDouble", this.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + let wrapped = new Array(); + let args = msg as Array; + let keyArg = args[0] as string; + let valueArg = args[1] as number; + api.setDouble(keyArg, valueArg).then(() => { + wrapped.push(true); + reply.reply(wrapped) + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to setDouble. code =" + err.code +", message =" + err.message); + let errs = wrapError(err); + wrapped = errs; + reply.reply(wrapped) + }) + } + }); + } else { + channel.setMessageHandler(null) + } + } + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setBool", this.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + let wrapped = new Array(); + let args = msg as Array; + let keyArg = args[0] as string; + let valueArg = args[1] as boolean; + api.setBool(keyArg, valueArg).then(() => { + wrapped.push(true); + reply.reply(wrapped) + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to setBool. code =" + err.code +", message =" + err.message); + let errs = wrapError(err); + wrapped = errs; + reply.reply(wrapped) + }) + } + }); + } else { + channel.setMessageHandler(null) + } + } + { + let channel = new BasicMessageChannel( + binaryMessenger, "dev.flutter.pigeon.shared_preferences_ohos.SharedPreferencesApi.setStringList", this.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage(msg: Object, reply: Reply): void { + let wrapped = new Array(); + let args = msg as Array; + let keyArg = args[0] as string; + let valueArg = args[1] as Array; + api.setStringList(keyArg, valueArg).then(() => { + wrapped.push(true); + reply.reply(wrapped) + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to setStringList. code =" + err.code +", message =" + err.message); + let errs = wrapError(err); + wrapped = errs; + reply.reply(wrapped) + }) + } + }); + } else { + channel.setMessageHandler(null) + } + } + } + + remove(key: string): boolean { + try { + let result = true + this.preferences?.delete(key,async (err: ESObject) => { + if (err) { + Log.w(TAG, "Failed to delete. message =" + err.message); + result = false; + } + Log.i(TAG, "Succeeded in deleting."); + await this.preferences?.flush(); + }) + return result; + } catch (err) { + Log.e(TAG, "Failed to delete. " + JSON.stringify(err)); + return false; + } + } + + setString(key: string, value: string): Promise { + if (value.startsWith(LIST_IDENTIFIER)) { + throw new Error( + "StorageError: This string cannot be stored as it clashes with special identifier prefixes"); + } + return this.put(key, value); + } + + setInt(key: string, value: number): Promise { + if(typeof value == "bigint") { + return this.put(key, Number(value)); + } + return this.put(key, value); + } + + put(key: string, value: ESObject): Promise { + try { + if (this.preferences == null) { + return new Promise((reject) => { + reject(); + }); + } else { + this.preferences.put(key, value); + return this.preferences.flush(); + } + } catch(err) { + Log.w(TAG, "Failed to put value of 'startup'. " + JSON.stringify(err)); + return new Promise((reject) => { + reject(); + }); + } + } + + setDouble(key: string, value: number): Promise { + return this.put(key, value); + } + + setStringList(key: string, value: string[]): Promise { + Log.w(TAG, "setStringList :" + value); + Log.w(TAG, "setStringList encoded:" + (LIST_IDENTIFIER + this.listEncoder.encode(value))); + return this.put(key, LIST_IDENTIFIER + this.listEncoder.encode(value)); + } + + clear(prefix: string, allowList: string[]): Promise { + try { + this.preferences?.getAll().then((value: object) => { + let allKeys = Object.keys(value); + for (let key of allKeys) { + if (key.startsWith(prefix) && (allowList == null || allowList.indexOf(key) != -1)) { + this.preferences?.delete(key); + } + } + return this.preferences?.flush(); + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to clear." + JSON.stringify(err)); + }); + } catch (err) { + Log.w(TAG, "Failed to clear." + JSON.stringify(err)); + } + return new Promise((reject) => { + reject(); + }) + } + + filterData(value: [string, Object], prefix: string, allowList: string[]): Map { + let allVal = Object.entries(value); + let filteredPrefs = new Map(); + for (let val of allVal) { + let key = val[0]; + let v = val[1]; + if (key.startsWith(prefix) && (allowList == null || allowList.indexOf(key) != -1)) { + filteredPrefs.set(key, this.transformPref(v)); + Log.w(TAG, "filterData00:key:" + key + " val:" + (this.transformPref(v))); + } + } + Log.w(TAG, "filterData1:" + JSON.stringify(filteredPrefs)); + return filteredPrefs; + } + + async getAll(prefix: string, allowList: Array): Promise { + try { + let res = new Map(); + if (this.preferences == null) { + return new Promise((reject) => { + reject("Failed to getAll"); + }) + } + await this.preferences.getAll().then((obj: Object) => { + res = this.filterData(obj as [string, ESObject], prefix, allowList); + }) + return new Promise((resolve) => { + resolve(res); + }) + } catch (err) { + Log.w(TAG, "Failed to excute getAll." + JSON.stringify(err)); + return new Promise((reject) => { + reject("Failed to getAll"); + }) + } + } + + getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + try { + let promise = data_preferences.getPreferences(binding.getApplicationContext(), PREFERENCES_NAME); + promise.then((object) => { + this.preferences = object; + Log.i(TAG, "Succeeded in getting preferences."); + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to get preferences. code =" + err.code + ", message =" + err.message); + }) + } catch(err) { + Log.w(TAG, "Failed to get preferences."+ JSON.stringify(err)); + } + this.setup(binding.getBinaryMessenger(), this); + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + try { + let promise = this.preferences?.flush(); + promise?.then(() => { + Log.i(TAG, "Succeeded in flushing."); + }).catch((err: ESObject) => { + Log.w(TAG, "Failed to flush." + JSON.stringify(err)); + }) + } catch (err) { + Log.w(TAG, "Failed to flush." + JSON.stringify(err)); + } + this.setup(binding.getBinaryMessenger(), null); + } + + setBool(key: string, value: boolean): Promise { + return this.put(key, value) + } + + transformPref(value: Object): Object { + if (typeof value == "string") { + let stringValue = (value as string); + if (stringValue.startsWith(LIST_IDENTIFIER)) { + let strList: ESObject = this.listEncoder.decode(stringValue.substring(LIST_IDENTIFIER.length)); + let t: ESObject = JSON.parse(strList); + return t; + } + } + return value; + } +} + +class ListEncoder implements SharedPreferencesListEncoder { + encode(list: string[]): string { + try { + let jsonList = JSON.stringify(list) + return buffer.from(jsonList).toString('base64');; + } catch (err) { + Log.e(TAG, "Failed encode." + JSON.stringify(err)); + } + return '' + } + + decode(listString: string): ESObject { + try { + let buf = buffer.from(listString, 'base64'); + return buf.toString(); + } catch (err) { + Log.e(TAG, "Failed decode." + JSON.stringify(err)); + } + return undefined + } +} diff --git a/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/module.json5 b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a00cd2a12b65e2db0b5cd20425d271847eb5f622 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/ohos/src/main/module.json5 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "module": { + "name": "shared_preferences_ohos", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/pubspec.yaml b/packages/shared_preferences/shared_preferences_ohos/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2c46a846c5580e289a9b63c982d543bcf5a019a2 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/pubspec.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: shared_preferences_ohos +description: Ohos implementation of the shared_preferences plugin +repository: https://gitee.com/openharmony-sig/flutter_packages/tree/master/packages/shared_preferences/shared_preferences_ohos +issue_tracker: https://gitee.com/openharmony-sig/flutter_packages/issues +version: 2.3.1 + +environment: + sdk: ^3.4.0 + flutter: ">=3.19.0" + +flutter: + plugin: + implements: shared_preferences + platforms: + ohos: + package: io.flutter.plugins.sharedpreferences + pluginClass: SharedPreferencesPlugin + dartPluginClass: SharedPreferencesOhos + +dependencies: + flutter: + sdk: flutter + shared_preferences_platform_interface: ^2.4.0 + +dev_dependencies: + flutter_test: + sdk: flutter + pigeon: ^16.0.4 + +topics: + - persistence + - shared-preferences + - storage \ No newline at end of file diff --git a/packages/shared_preferences/shared_preferences_ohos/test/shared_preferences_ohos_test.dart b/packages/shared_preferences/shared_preferences_ohos/test/shared_preferences_ohos_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ae6889286434008c0873928937601d0ad9f38359 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_ohos/test/shared_preferences_ohos_test.dart @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences_ohos/shared_preferences_ohos.dart'; +import 'package:shared_preferences_ohos/src/messages.g.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_platform_interface/types.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + late _FakeSharedPreferencesApi api; + late SharedPreferencesOhos plugin; + + const Map flutterTestValues = { + 'flutter.String': 'hello world', + 'flutter.Bool': true, + 'flutter.Int': 42, + 'flutter.Double': 3.14159, + 'flutter.StringList': ['foo', 'bar'], + }; + + const Map prefixTestValues = { + 'prefix.String': 'hello world', + 'prefix.Bool': true, + 'prefix.Int': 42, + 'prefix.Double': 3.14159, + 'prefix.StringList': ['foo', 'bar'], + }; + + const Map nonPrefixTestValues = { + 'String': 'hello world', + 'Bool': true, + 'Int': 42, + 'Double': 3.14159, + 'StringList': ['foo', 'bar'], + }; + + final Map allTestValues = {}; + + allTestValues.addAll(flutterTestValues); + allTestValues.addAll(prefixTestValues); + allTestValues.addAll(nonPrefixTestValues); + + setUp(() { + api = _FakeSharedPreferencesApi(); + plugin = SharedPreferencesOhos(api: api); + }); + + test('registerWith', () { + SharedPreferencesOhos.registerWith(); + expect(SharedPreferencesStorePlatform.instance, + isA()); + }); + + test('remove', () async { + api.items['flutter.hi'] = 'world'; + expect(await plugin.remove('flutter.hi'), isTrue); + expect(api.items.containsKey('flutter.hi'), isFalse); + }); + + test('clear', () async { + api.items['flutter.hi'] = 'world'; + expect(await plugin.clear(), isTrue); + expect(api.items.containsKey('flutter.hi'), isFalse); + }); + + test('clearWithPrefix', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + + Map all = await plugin.getAllWithPrefix('prefix.'); + expect(all.length, 5); + await plugin.clearWithPrefix('prefix.'); + all = await plugin.getAll(); + expect(all.length, 5); + all = await plugin.getAllWithPrefix('prefix.'); + expect(all.length, 0); + }); + + test('clearWithParameters', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + + Map all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(all.length, 5); + await plugin.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + all = await plugin.getAll(); + expect(all.length, 5); + all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(all.length, 0); + }); + + test('clearWithParameters with allow list', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + + Map all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(all.length, 5); + await plugin.clearWithParameters( + ClearParameters( + filter: PreferencesFilter( + prefix: 'prefix.', + allowList: {'prefix.StringList'}, + ), + ), + ); + all = await plugin.getAll(); + expect(all.length, 5); + all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(all.length, 4); + }); + + test('getAll', () async { + for (final String key in flutterTestValues.keys) { + api.items[key] = flutterTestValues[key]!; + } + final Map all = await plugin.getAll(); + expect(all.length, 5); + expect(all, flutterTestValues); + }); + + test('getAllWithNoPrefix', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + final Map all = await plugin.getAllWithPrefix(''); + expect(all.length, 15); + expect(all, allTestValues); + }); + + test('clearWithNoPrefix', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + + Map all = await plugin.getAllWithPrefix(''); + expect(all.length, 15); + await plugin.clearWithPrefix(''); + all = await plugin.getAllWithPrefix(''); + expect(all.length, 0); + }); + + test('getAllWithParameters', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + final Map all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: 'prefix.'), + ), + ); + expect(all.length, 5); + expect(all, prefixTestValues); + }); + + test('getAllWithParameters with allow list', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + final Map all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter( + prefix: 'prefix.', + allowList: {'prefix.Bool'}, + ), + ), + ); + expect(all.length, 1); + expect(all['prefix.Bool'], true); + }); + + test('setValue', () async { + expect(await plugin.setValue('Bool', 'flutter.Bool', true), isTrue); + expect(api.items['flutter.Bool'], true); + expect(await plugin.setValue('Double', 'flutter.Double', 1.5), isTrue); + expect(api.items['flutter.Double'], 1.5); + expect(await plugin.setValue('Int', 'flutter.Int', 12), isTrue); + expect(api.items['flutter.Int'], 12); + expect(await plugin.setValue('String', 'flutter.String', 'hi'), isTrue); + expect(api.items['flutter.String'], 'hi'); + expect( + await plugin + .setValue('StringList', 'flutter.StringList', ['hi']), + isTrue); + expect(api.items['flutter.StringList'], ['hi']); + }); + + test('setValue with unsupported type', () { + expect(() async { + await plugin.setValue('Map', 'flutter.key', {}); + }, throwsA(isA())); + }); + + test('getAllWithNoPrefix', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + final Map all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(all.length, 15); + expect(all, allTestValues); + }); + + test('clearWithNoPrefix', () async { + for (final String key in allTestValues.keys) { + api.items[key] = allTestValues[key]!; + } + + Map all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(all.length, 15); + await plugin.clearWithParameters( + ClearParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + all = await plugin.getAllWithParameters( + GetAllParameters( + filter: PreferencesFilter(prefix: ''), + ), + ); + expect(all.length, 0); + }); +} + +class _FakeSharedPreferencesApi implements SharedPreferencesApi { + final Map items = {}; + + @override + Future> getAll( + String prefix, + List? allowList, + ) async { + Set? allowSet; + if (allowList != null) { + allowSet = Set.from(allowList); + } + return { + for (final String key in items.keys) + if (key.startsWith(prefix) && + (allowSet == null || allowSet.contains(key))) + key: items[key] + }; + } + + @override + Future remove(String key) async { + items.remove(key); + return true; + } + + @override + Future setBool(String key, bool value) async { + items[key] = value; + return true; + } + + @override + Future setDouble(String key, double value) async { + items[key] = value; + return true; + } + + @override + Future clear(String prefix, List? allowList) async { + items.keys.toList().forEach((String key) { + if (key.startsWith(prefix) && + (allowList == null || allowList.contains(key))) { + items.remove(key); + } + }); + return true; + } + + @override + Future setInt(String key, Object value) async { + items[key] = value; + return true; + } + + @override + Future setString(String key, String value) async { + items[key] = value; + return true; + } + + @override + Future setStringList(String key, List value) async { + items[key] = value; + return true; + } +}