diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 0000000000000000000000000000000000000000..9a90959c6e5110fcb89023d2b99630ddddbacff4 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app_links/ohos/.gitignore b/app_links/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ac5aa9893e489c2ce51135893f258c60a475bb7a --- /dev/null +++ b/app_links/ohos/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/app_links/ohos/.metadata b/app_links/ohos/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..ea72294e78ca44f30a1d80c776a5cde20cd11447 --- /dev/null +++ b/app_links/ohos/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "17f34a33bd784a87bd6a5ea479491b83631fd9e0" + channel: "oh-3.22.0" + +project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0 + base_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0 + - platform: ohos + create_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0 + base_revision: 17f34a33bd784a87bd6a5ea479491b83631fd9e0 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/app_links/ohos/CHANGELOG.md b/app_links/ohos/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..abd84ca152910f0f8124ed1c63a1b2b4378c2dc4 --- /dev/null +++ b/app_links/ohos/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +* Support OpenHarmony. \ No newline at end of file diff --git a/app_links/ohos/LICENSE b/app_links/ohos/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/app_links/ohos/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/app_links/ohos/README.md b/app_links/ohos/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bd0e508bafa99581993d290111b98d88241ed59a --- /dev/null +++ b/app_links/ohos/README.md @@ -0,0 +1,46 @@ +# HarmonyOS + +HarmonyOS documentation: +- App Links: [Documentation](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-linking-startup-V5) +- Deep Links: [Documentation](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/deep-linking-startup-V5) + +## Usage + +```yaml +dependencies: + app_links: 6.3.2 + app_links_ohos: 1.0.0 +``` + +## SETUP + +Add your setup: +```sh + + { + "module": { + // ... + "abilities": [ + { + // ... + "skills": [ + { + "uris": [ + { + "scheme": "sample", + "host": "open.my.app", + } + ] + } + ] + } + ] + } + } +``` + +# Testing + +```sh +"sample://open.my.app/#/book/hello-world" +``` \ No newline at end of file diff --git a/app_links/ohos/analysis_options.yaml b/app_links/ohos/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a5744c1cfbe77ae2daba29c74156c617b5f09b77 --- /dev/null +++ b/app_links/ohos/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/app_links/ohos/example/.gitignore b/app_links/ohos/example/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..29a3a5017f048d6d8e6a450eef64435ddee44fb7 --- /dev/null +++ b/app_links/ohos/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/app_links/ohos/example/README.md b/app_links/ohos/example/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8e291c6a0596551011ee1e7b7bb7b8992c10d57c --- /dev/null +++ b/app_links/ohos/example/README.md @@ -0,0 +1,16 @@ +# app_links_ohos_example + +Demonstrates how to use the app_links_ohos plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/app_links/ohos/example/analysis_options.yaml b/app_links/ohos/example/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0d2902135caece481a035652d88970c80e29cc7e --- /dev/null +++ b/app_links/ohos/example/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/app_links/ohos/example/integration_test/plugin_integration_test.dart b/app_links/ohos/example/integration_test/plugin_integration_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a8c192303cae3824f47a06f8446b0a7216dd31f4 --- /dev/null +++ b/app_links/ohos/example/integration_test/plugin_integration_test.dart @@ -0,0 +1,25 @@ +// This is a basic Flutter integration test. +// +// Since integration tests run in a full Flutter application, they can interact +// with the host side of a plugin implementation, unlike Dart unit tests. +// +// For more information about Flutter integration tests, please see +// https://docs.flutter.dev/cookbook/testing/integration/introduction + + +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:app_links_ohos/app_links_ohos.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('getPlatformVersion test', (WidgetTester tester) async { + final AppLinksOhos plugin = AppLinksOhos(); + final String? version = await plugin.getPlatformVersion(); + // The version string depends on the host platform running the test, so + // just assert that some non-empty string is returned. + expect(version?.isNotEmpty, true); + }); +} diff --git a/app_links/ohos/example/lib/main.dart b/app_links/ohos/example/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..4212aaab419a8c4b67ca1902356d44a648857ea7 --- /dev/null +++ b/app_links/ohos/example/lib/main.dart @@ -0,0 +1,158 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:app_links/app_links.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'url_protocol/api.dart'; +import 'package:app_links_platform_interface/app_links_platform_interface.dart'; + +/////////////////////////////////////////////////////////////////////////////// +/// Please make sure to follow the setup instructions below +/// +/// Please take a look at: +/// - example/android/app/main/AndroidManifest.xml for Android. +/// +/// - example/ios/Runner/Runner.entitlements for Universal Link sample. +/// - example/ios/Runner/Info.plist for Custom URL scheme sample. +/// +/// You can launch an intent on an Android Emulator like this: +/// adb shell am start -a android.intent.action.VIEW \ +/// -d "sample://open.my.app/#/book/hello-world" +/// +/// +/// On windows & macOS: +/// The simplest way to test it is by +/// opening your browser and type: sample://foo/#/book/hello-world2 +/// +/// On windows: +/// Outside of a browser, in a email for example, you can use: +/// https://example.com/#/book/hello-world2 +/////////////////////////////////////////////////////////////////////////////// + +const kWindowsScheme = 'sample'; + +void main() { + // Register our protocol only on Windows platform + // registerProtocolHandler(kWindowsScheme); + + runApp(const MyApp()); +} + +class MyApp extends StatefulWidget { + const MyApp({Key? key}) : super(key: key); + + @override + State createState() => _MyAppState(); +} + +class _MyAppState extends State { + final _navigatorKey = GlobalKey(); + late AppLinks _appLinks; + StreamSubscription? _linkSubscription; + + @override + void initState() { + super.initState(); + + initDeepLinks(); + } + + @override + void dispose() { + _linkSubscription?.cancel(); + + super.dispose(); + } + + Future initDeepLinks() async { + _appLinks = AppLinks(); + + // Handle links + _linkSubscription = _appLinks.uriLinkStream.listen((uri) { + debugPrint('onAppLink: $uri'); + openAppLink(uri); + }); + } + + void openAppLink(Uri uri) { + print("测试打印日志"); + print(AppLinksPlatform.instance.getInitialLinkString()); + print(AppLinksPlatform.instance.getLatestLinkString()); + _navigatorKey.currentState?.pushNamed(uri.fragment); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + navigatorKey: _navigatorKey, + initialRoute: "/", + onGenerateRoute: (RouteSettings settings) { + Widget routeWidget = defaultScreen(); + + // Mimic web routing + final routeName = settings.name; + if (routeName != null) { + if (routeName.startsWith('/book/')) { + // Navigated to /book/:id + routeWidget = customScreen( + routeName.substring(routeName.indexOf('/book/')), + ); + } else if (routeName == '/book') { + // Navigated to /book without other parameters + routeWidget = customScreen("None"); + } + } + + return MaterialPageRoute( + builder: (context) => routeWidget, + settings: settings, + fullscreenDialog: true, + ); + }, + ); + } + + Widget defaultScreen() { + return Scaffold( + appBar: AppBar(title: const Text('Default Screen')), + body: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SelectableText(''' + Launch an intent to get to the second screen. + + On web: + http://localhost:/#/book/1 for example. + + On windows & macOS, open your browser: + sample://foo/#/book/hello-deep-linking + + This example code triggers new page from URL fragment. + '''), + const SizedBox(height: 20), + buildWindowsUnregisterBtn(), + ], + ), + ), + ); + } + + Widget customScreen(String bookId) { + return Scaffold( + appBar: AppBar(title: const Text('Second Screen')), + body: Center(child: Text('Opened with parameter: $bookId')), + ); + } + + Widget buildWindowsUnregisterBtn() { + if (defaultTargetPlatform == TargetPlatform.windows) { + return TextButton( + onPressed: () => unregisterProtocolHandler(kWindowsScheme), + child: const Text('Remove Windows protocol registration')); + } + + return const SizedBox.shrink(); + } +} diff --git a/app_links/ohos/example/lib/url_protocol/api.dart b/app_links/ohos/example/lib/url_protocol/api.dart new file mode 100644 index 0000000000000000000000000000000000000000..fde211fa44f020fb91b5c0a715e3cdd788bb78c4 --- /dev/null +++ b/app_links/ohos/example/lib/url_protocol/api.dart @@ -0,0 +1,43 @@ +import 'protocol.dart'; +import 'windows_protocol.dart' + if (dart.library.js_interop) 'web_url_protocol.dart'; + +/// Registers a protocol by [scheme] to allow for links in the form `://...` +/// to be processed by this application. By default, opening a link will open +/// the executable that was used to register the scheme with the URL as the first +/// argument passed to the executable. +/// +/// If a protocol is already registered for the given scheme, this function will +/// attempt to overwrite the previous handler with the current executable information. +/// However, note that depending on process permissions, this operation may be +/// disallowed by the underlying platform. +/// +/// You may pass an [executable] to override the path to the executable to run +/// when accessing the URL. +/// +/// [arguments] is a list of arguments to be used when running the executable. +/// If passed, the list must contain at least one element, and at least one of +/// those elements must contain the literal value `%s` to denote the URL to open. +/// Quoting arguments is not necessary, as this will be handled for you. +/// Escaping the `%s` as an unprocessed literal is currently unsupported. +void registerProtocolHandler( + String scheme, { + String? executable, + List? arguments, +}) { + WindowsProtocolHandler().register( + scheme, + executable: executable, + arguments: arguments, + ); +} + +/// Unregisters the protocol handler with the underlying platform. The provided +/// [scheme] will no longer be used in links. +/// +/// Note that this will unregister a protocol by scheme regardless of which process +/// had registered it. Unregistering a scheme that was not registered by this +/// application is undefined and depends on platform-specific restrictions. +void unregisterProtocolHandler(String scheme) { + WindowsProtocolHandler().unregister(scheme); +} diff --git a/app_links/ohos/example/lib/url_protocol/protocol.dart b/app_links/ohos/example/lib/url_protocol/protocol.dart new file mode 100644 index 0000000000000000000000000000000000000000..882e5560de0fef800efdd921d9e10e7d105ae94d --- /dev/null +++ b/app_links/ohos/example/lib/url_protocol/protocol.dart @@ -0,0 +1,15 @@ +abstract class ProtocolHandler { + void register(String scheme, {String? executable, List? arguments}); + + void unregister(String scheme); + + List getArguments(List? arguments) { + if (arguments == null) return ['%s']; + + if (arguments.isEmpty && !arguments.any((e) => e.contains('%s'))) { + throw ArgumentError('arguments must contain at least 1 instance of "%s"'); + } + + return arguments; + } +} diff --git a/app_links/ohos/example/lib/url_protocol/web_url_protocol.dart b/app_links/ohos/example/lib/url_protocol/web_url_protocol.dart new file mode 100644 index 0000000000000000000000000000000000000000..cc17847fba1c0d9ee7f4d8e488cf4903a389c494 --- /dev/null +++ b/app_links/ohos/example/lib/url_protocol/web_url_protocol.dart @@ -0,0 +1,9 @@ +import './protocol.dart'; + +class WindowsProtocolHandler extends ProtocolHandler { + @override + void register(String scheme, {String? executable, List? arguments}) {} + + @override + void unregister(String scheme) {} +} diff --git a/app_links/ohos/example/lib/url_protocol/windows_protocol.dart b/app_links/ohos/example/lib/url_protocol/windows_protocol.dart new file mode 100644 index 0000000000000000000000000000000000000000..5fe605f093cc54b8fe166f594fefbf4d16484735 --- /dev/null +++ b/app_links/ohos/example/lib/url_protocol/windows_protocol.dart @@ -0,0 +1,65 @@ +import 'dart:io'; + +import 'package:ffi/ffi.dart'; +import 'package:flutter/foundation.dart'; +import 'package:win32/win32.dart'; + +import './protocol.dart'; + +const _hive = HKEY_CURRENT_USER; + +class WindowsProtocolHandler extends ProtocolHandler { + @override + void register(String scheme, {String? executable, List? arguments}) { + if (defaultTargetPlatform != TargetPlatform.windows) return; + + final prefix = _regPrefix(scheme); + final capitalized = scheme[0].toUpperCase() + scheme.substring(1); + final args = getArguments(arguments).map((a) => _sanitize(a)); + final cmd = + '${executable ?? Platform.resolvedExecutable} ${args.join(' ')}'; + + _regCreateStringKey(_hive, prefix, '', 'URL:$capitalized'); + _regCreateStringKey(_hive, prefix, 'URL Protocol', ''); + _regCreateStringKey(_hive, '$prefix\\shell\\open\\command', '', cmd); + } + + @override + void unregister(String scheme) { + if (defaultTargetPlatform != TargetPlatform.windows) return; + + final txtKey = TEXT(_regPrefix(scheme)); + try { + RegDeleteTree(HKEY_CURRENT_USER, txtKey); + } finally { + free(txtKey); + } + } + + String _regPrefix(String scheme) => 'SOFTWARE\\Classes\\$scheme'; + + int _regCreateStringKey(int hKey, String key, String valueName, String data) { + final txtKey = TEXT(key); + final txtValue = TEXT(valueName); + final txtData = TEXT(data); + try { + return RegSetKeyValue( + hKey, + txtKey, + txtValue, + REG_SZ, + txtData, + txtData.length * 2 + 2, + ); + } finally { + free(txtKey); + free(txtValue); + free(txtData); + } + } + + String _sanitize(String value) { + value = value.replaceAll(r'%s', '%1').replaceAll(r'"', '\\"'); + return '"$value"'; + } +} diff --git a/app_links/ohos/example/ohos/.gitignore b/app_links/ohos/example/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6ca13b3170eec5dd5ac5ad7f1c4dd0118845f473 --- /dev/null +++ b/app_links/ohos/example/ohos/.gitignore @@ -0,0 +1,19 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +*.har +**/BuildProfile.ets +**/oh-package-lock.json5 + +**/src/main/resources/rawfile/flutter_assets/ +**/libs/arm64-v8a/libapp.so +**/libs/arm64-v8a/libflutter.so +**/libs/arm64-v8a/libvmservice_snapshot.so diff --git a/app_links/ohos/example/ohos/AppScope/app.json5 b/app_links/ohos/example/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..44498cf93d84542c0661745f965482bcd8b0bf4a --- /dev/null +++ b/app_links/ohos/example/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.llfbandit.app_links.app_links_ohos_example", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/app_links/ohos/example/ohos/AppScope/resources/base/element/string.json b/app_links/ohos/example/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..62beaa2c9e615a1d2b5c5a41bbbb7496e45bfe63 --- /dev/null +++ b/app_links/ohos/example/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "app_links_ohos_example" + } + ] +} diff --git a/app_links/ohos/example/ohos/AppScope/resources/base/media/app_icon.png b/app_links/ohos/example/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/app_links/ohos/example/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/app_links/ohos/example/ohos/build-profile.json5 b/app_links/ohos/example/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..26bea001ac6999860a2890121e380c122e6b601b --- /dev/null +++ b/app_links/ohos/example/ohos/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "app": { + "signingConfigs": [ + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/.gitignore b/app_links/ohos/example/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/build-profile.json5 b/app_links/ohos/example/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/app_links/ohos/example/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* 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", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/hvigorfile.ts b/app_links/ohos/example/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/app_links/ohos/example/ohos/entry/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 { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/app_links/ohos/example/ohos/entry/oh-package.json5 b/app_links/ohos/example/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e951e1f2653e93f1502c5b160ca2eb58b84192b5 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "integration_test": "file:..\\har\\integration_test.har", + "app_links_ohos": "file:..\\har\\app_links_ohos.har" + } +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/app_links/ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8bc48be8773196f34cccb15cf517f87f5c6b94d2 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.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. +*/ + +import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos'; +import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant'; + +export default class EntryAbility extends FlutterAbility { + configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + GeneratedPluginRegistrant.registerWith(flutterEngine) + } +} diff --git a/app_links/ohos/example/ohos/entry/src/main/ets/pages/Index.ets b/app_links/ohos/example/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..1125f9fdd95f4310a182c1c9e3680f37f73686c9 --- /dev/null +++ b/app_links/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/app_links/ohos/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets b/app_links/ohos/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets new file mode 100644 index 0000000000000000000000000000000000000000..8361eef5ca93a83688886465f5dd025b8cffe103 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2024 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 { FlutterEngine, Log } from '@ohos/flutter_ohos'; +import AppLinksOhosPlugin from 'app_links_ohos'; +import IntegrationTestPlugin from 'integration_test'; + +/** + * Generated file. Do not edit. + * This file is generated by the Flutter tool based on the + * plugins that support the Ohos platform. + */ + +const TAG = "GeneratedPluginRegistrant"; + +export class GeneratedPluginRegistrant { + + static registerWith(flutterEngine: FlutterEngine) { + try { + flutterEngine.getPlugins()?.add(new AppLinksOhosPlugin()); + flutterEngine.getPlugins()?.add(new IntegrationTestPlugin()); + } catch (e) { + Log.e( + TAG, + "Tried to register plugins with FlutterEngine (" + + flutterEngine + + ") failed."); + Log.e(TAG, "Received exception while registering", e); + } + } +} diff --git a/app_links/ohos/example/ohos/entry/src/main/module.json5 b/app_links/ohos/example/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..867f1c443694218b48c1e61be7c1aa3001e4d958 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/main/module.json5 @@ -0,0 +1,59 @@ +/* +* 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" + ], + "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" + ], + "uris": [ + { + "scheme": 'sample', + "host": "open.my.app", + } + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/base/element/color.json b/app_links/ohos/example/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/app_links/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/app_links/ohos/example/ohos/entry/src/main/resources/base/element/string.json b/app_links/ohos/example/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..d9e50ac2b73f1a0445d51d530b8963be95042df1 --- /dev/null +++ b/app_links/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": "app_links_ohos_example" + } + ] +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/base/media/icon.png b/app_links/ohos/example/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/app_links/ohos/example/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json b/app_links/ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/en_US/element/string.json b/app_links/ohos/example/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..d9e50ac2b73f1a0445d51d530b8963be95042df1 --- /dev/null +++ b/app_links/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": "app_links_ohos_example" + } + ] +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json b/app_links/ohos/example/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..2679adea6dd819ae687a8992e2f74528027f6e6c --- /dev/null +++ b/app_links/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": "app_links_ohos_example" + } + ] +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -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. +*/ + +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/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* 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/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -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 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'; + +export default class TestAbility extends UIAbility { + onCreate(want, 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/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.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'; + +@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/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -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 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/app_links/ohos/example/ohos/entry/src/ohosTest/module.json5 b/app_links/ohos/example/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/ohosTest/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_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/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/app_links/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/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/app_links/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/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/app_links/ohos/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/app_links/ohos/example/ohos/hvigor/hvigor-config.json5 b/app_links/ohos/example/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a9eb4b3a4f416a6adae837be5e6c79e7d734b5d4 --- /dev/null +++ b/app_links/ohos/example/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,23 @@ +/* +* 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. +*/ + +{ + "modelVersion": "5.0.0", + "dependencies": { + }, + 'properties': { + "ohos.nativeResolver": false + } +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/hvigorfile.ts b/app_links/ohos/example/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f2d2aafe6d6a3a71a9944ebd0c91fbc308ac9d1 --- /dev/null +++ b/app_links/ohos/example/ohos/hvigorfile.ts @@ -0,0 +1,21 @@ +/* +* 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 { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/app_links/ohos/example/ohos/oh-package.json5 b/app_links/ohos/example/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..76c20a296eb37e56cbbee810baaf34e560ea300c --- /dev/null +++ b/app_links/ohos/example/ohos/oh-package.json5 @@ -0,0 +1,21 @@ +{ + "modelVersion": "5.0.0", + "name": "app_links_ohos_example", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "@ohos/flutter_ohos": "file:./har/flutter.har" + }, + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "overrides": { + "@ohos/flutter_ohos": "file:./har/flutter.har", + "integration_test": "file:./har/integration_test.har", + "app_links_ohos": "file:./har/app_links_ohos.har", + "@ohos/flutter_module": "file:./entry" + } +} \ No newline at end of file diff --git a/app_links/ohos/example/pubspec.yaml b/app_links/ohos/example/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..dcddbeeb88c63484b72b484e0191f98f8f387cf1 --- /dev/null +++ b/app_links/ohos/example/pubspec.yaml @@ -0,0 +1,104 @@ +name: app_links_ohos_example +description: "Demonstrates how to use the app_links_ohos plugin." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +environment: +# sdk: '>=3.4.0 <4.0.0' + + sdk: ^3.3.0 + flutter: ">=3.19.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + app_links_ohos: + # When depending on this package from a real application you should use: + # app_links_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: ../ + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.6 + + app_links: ^6.1.3 + + ffi: ^2.1.0 + win32: ^5.1.0 + +dev_dependencies: + integration_test: + sdk: flutter + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + + msix: ^3.16.8 + +# flutter_lints: ^3.0.0 + flutter_lints: ^4.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages + +# Windows only (packaged app) +msix_config: + display_name: app_links_example + msix_version: 1.0.0.0 + protocol_activation: https, sample # Add the protocol activation for the app + app_uri_handler_hosts: www.example.com, example.com # Add the app uri handler hosts diff --git a/app_links/ohos/example/test/widget_test.dart b/app_links/ohos/example/test/widget_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..6ecdd6917403e250c931b3523355168e7bb924f0 --- /dev/null +++ b/app_links/ohos/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:app_links_ohos_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data!.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/app_links/ohos/lib/app_links.dart b/app_links/ohos/lib/app_links.dart new file mode 100644 index 0000000000000000000000000000000000000000..07c6f343db9a9edcd3ef9b01620ef23036cc0c4f --- /dev/null +++ b/app_links/ohos/lib/app_links.dart @@ -0,0 +1 @@ +export 'src/app_links.dart'; diff --git a/app_links/ohos/lib/app_links_ohos.dart b/app_links/ohos/lib/app_links_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..15330d03cf1a1134c689b986cd7009fcc4bbefaa --- /dev/null +++ b/app_links/ohos/lib/app_links_ohos.dart @@ -0,0 +1,8 @@ + +import 'app_links_ohos_platform_interface.dart'; + +class AppLinksOhos { + Future getPlatformVersion() { + return AppLinksOhosPlatform.instance.getPlatformVersion(); + } +} diff --git a/app_links/ohos/lib/app_links_ohos_method_channel.dart b/app_links/ohos/lib/app_links_ohos_method_channel.dart new file mode 100644 index 0000000000000000000000000000000000000000..9c189967e94a3fa27b8fd79170f978ba2c3203c3 --- /dev/null +++ b/app_links/ohos/lib/app_links_ohos_method_channel.dart @@ -0,0 +1,17 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import 'app_links_ohos_platform_interface.dart'; + +/// An implementation of [AppLinksOhosPlatform] that uses method channels. +class MethodChannelAppLinksOhos extends AppLinksOhosPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + final methodChannel = const MethodChannel('app_links_ohos'); + + @override + Future getPlatformVersion() async { + final version = await methodChannel.invokeMethod('getPlatformVersion'); + return version; + } +} diff --git a/app_links/ohos/lib/app_links_ohos_platform_interface.dart b/app_links/ohos/lib/app_links_ohos_platform_interface.dart new file mode 100644 index 0000000000000000000000000000000000000000..2732ca52b976bbc96181d67ca9b04035a178de1f --- /dev/null +++ b/app_links/ohos/lib/app_links_ohos_platform_interface.dart @@ -0,0 +1,29 @@ +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'app_links_ohos_method_channel.dart'; + +abstract class AppLinksOhosPlatform extends PlatformInterface { + /// Constructs a AppLinksOhosPlatform. + AppLinksOhosPlatform() : super(token: _token); + + static final Object _token = Object(); + + static AppLinksOhosPlatform _instance = MethodChannelAppLinksOhos(); + + /// The default instance of [AppLinksOhosPlatform] to use. + /// + /// Defaults to [MethodChannelAppLinksOhos]. + static AppLinksOhosPlatform get instance => _instance; + + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [AppLinksOhosPlatform] when + /// they register themselves. + static set instance(AppLinksOhosPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + Future getPlatformVersion() { + throw UnimplementedError('platformVersion() has not been implemented.'); + } +} diff --git a/app_links/ohos/lib/src/app_links.dart b/app_links/ohos/lib/src/app_links.dart new file mode 100644 index 0000000000000000000000000000000000000000..a6152ea1c67a125a7c7a6a1bdc66555359af413e --- /dev/null +++ b/app_links/ohos/lib/src/app_links.dart @@ -0,0 +1,87 @@ +import 'dart:async'; +import "package:app_links_platform_interface/app_links_platform_interface.dart"; + +/// App links handler. +/// +/// This class is a singleton and should be accessed using `AppLinks()`. +class AppLinks extends AppLinksPlatform { + static final AppLinks _instance = AppLinks._(); + + factory AppLinks() => _instance; + + AppLinks._(); + + StreamController? _stringStreamController; + StreamController? _uriStreamController; + + @override + Future getInitialLink() { + return AppLinksPlatform.instance.getInitialLink(); + } + + @override + Future getInitialLinkString() { + return AppLinksPlatform.instance.getInitialLinkString(); + } + + @override + Future getLatestLink() { + return AppLinksPlatform.instance.getLatestLink(); + } + + @override + Future getLatestLinkString() { + return AppLinksPlatform.instance.getLatestLinkString(); + } + + @override + Stream get stringLinkStream { + if (_stringStreamController == null) { + _stringStreamController = StreamController.broadcast(); + + _initController( + _stringStreamController!, + AppLinksPlatform.instance.stringLinkStream, + onCancel: () => _stringStreamController = null, + ); + } + + return _stringStreamController!.stream; + } + + @override + Stream get uriLinkStream { + if (_uriStreamController == null) { + _uriStreamController = StreamController.broadcast(); + + _initController( + _uriStreamController!, + AppLinksPlatform.instance.uriLinkStream, + onCancel: () => _uriStreamController = null, + ); + } + + return _uriStreamController!.stream; + } + + void _initController( + StreamController controller, + Stream stream, { + required void Function() onCancel, + }) { + final subscription = stream.listen( + controller.add, + onError: controller.addError, + ); + + // Broadcast controller doesn't support pause/resume + // + // Forward cancel event when there's no more listeners + // and dispose controller + controller.onCancel = () async { + await subscription.cancel(); + await controller.close(); + onCancel(); + }; + } +} diff --git a/app_links/ohos/ohos/.gitignore b/app_links/ohos/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c0f9ca4c47ca2d6aea523c5e0cf3331566bbf88a --- /dev/null +++ b/app_links/ohos/ohos/.gitignore @@ -0,0 +1,9 @@ +/node_modules +/oh_modules +/.preview +/.idea +/build +/.cxx +/.test +/BuildProfile.ets +/oh-package-lock.json5 diff --git a/app_links/ohos/ohos/build-profile.json5 b/app_links/ohos/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..79961f96a6fe0507354b7952a378c3be2ae4bfab --- /dev/null +++ b/app_links/ohos/ohos/build-profile.json5 @@ -0,0 +1,10 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/app_links/ohos/ohos/hvigorfile.ts b/app_links/ohos/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..47e6e1f81d365872f101585f5dbf816bcad65864 --- /dev/null +++ b/app_links/ohos/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 { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/app_links/ohos/ohos/index.ets b/app_links/ohos/ohos/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..39d5185512e1ed3451e0c7d0031b43ec73e1c46e --- /dev/null +++ b/app_links/ohos/ohos/index.ets @@ -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. +*/ + +import AppLinksOhosPlugin from './src/main/ets/components/plugin/AppLinksOhosPlugin'; +export default AppLinksOhosPlugin; diff --git a/app_links/ohos/ohos/local.properties b/app_links/ohos/ohos/local.properties new file mode 100644 index 0000000000000000000000000000000000000000..f68f693dcae4ef8db5d5bc427813131d1e540262 --- /dev/null +++ b/app_links/ohos/ohos/local.properties @@ -0,0 +1 @@ +hwsdk.dir=E:\\Huawei4.0\\Sdk \ No newline at end of file diff --git a/app_links/ohos/ohos/oh-package.json5 b/app_links/ohos/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6c1b23388526ad59eda9b5586283e50cb97c79b6 --- /dev/null +++ b/app_links/ohos/ohos/oh-package.json5 @@ -0,0 +1,11 @@ +{ + "name": "app_links_ohos", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "index.ets", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@ohos/flutter_ohos": "file:./har/flutter.har" + } +} diff --git a/app_links/ohos/ohos/src/main/ets/components/plugin/AppLinksOhosPlugin.ets b/app_links/ohos/ohos/src/main/ets/components/plugin/AppLinksOhosPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..3939f204a4d55774f5ae277cafd78eef9e47e010 --- /dev/null +++ b/app_links/ohos/ohos/src/main/ets/components/plugin/AppLinksOhosPlugin.ets @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2024 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 { + AbilityAware, + AbilityPluginBinding, + Any, + FlutterPlugin, + FlutterPluginBinding, + MethodCall, + MethodCallHandler, + MethodChannel, + MethodResult, + NewWantListener, +} from '@ohos/flutter_ohos'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import Want from '@ohos.app.ability.Want'; +import EventChannel, { EventSink, StreamHandler } from '@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel'; + +/** AppLinksOhosPlugin **/ +export default class AppLinksOhosPlugin implements FlutterPlugin, MethodCallHandler, NewWantListener, StreamHandler, AbilityAware { + private channel: MethodChannel | null = null; + private eventChannel: EventChannel | null = null; + private initialLink: String | null = null; + private latestLink: String | null = null; + private eventSink: EventSink | null = null; + + constructor() { + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + if (binding.getAbility().launchWant) { + this.initialLink = binding.getAbility().launchWant.uri || null; + this.latestLink = binding.getAbility().launchWant.uri || null; + } + binding.addOnNewWantListener(this); + } + + onDetachedFromAbility(): void { + throw new Error('Method not implemented.'); + } + + onListen(args: Any, events: EventSink): void { + throw new Error('Method not implemented.'); + } + + onCancel(args: Any): void { + throw new Error('Method not implemented.'); + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + if (want.uri) { + this.latestLink = want.uri; + this.eventSink?.success(want.uri); + } else { + this.eventSink?.success(null); + } + } + + getUniqueClassName(): string { + return "AppLinksOhosPlugin" + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.channel = new MethodChannel(binding.getBinaryMessenger(), "com.llfbandit.app_links/messages"); + this.channel.setMethodCallHandler(this); + this.eventChannel = new EventChannel(binding.getBinaryMessenger(), "com.llfbandit.app_links/events"); + this.eventChannel.setStreamHandler({ + onListen: (args: Object, eventSink: EventSink) => { + this.eventSink = eventSink; + if (this.initialLink) { + eventSink.success(this.initialLink); + } + }, + onCancel: () => { + } + }); + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + if (this.channel != null) { + this.channel.setMethodCallHandler(null); + } + if (this.eventChannel != null) { + this.eventChannel.setStreamHandler(null); + } + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + if (call.method == "getLatestLink") { + result.success(this.latestLink); + } else if (call.method == "getInitialLink") { + result.success(this.initialLink); + } else { + result.notImplemented(); + } + } +} \ No newline at end of file diff --git a/app_links/ohos/ohos/src/main/module.json5 b/app_links/ohos/ohos/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d7d8888fd90fb04a81f7f7af12624615b5607f5a --- /dev/null +++ b/app_links/ohos/ohos/src/main/module.json5 @@ -0,0 +1,10 @@ +{ + "module": { + "name": "app_links_ohos", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/app_links/ohos/pubspec.yaml b/app_links/ohos/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c1868dac1ed662c87958df3d732df367ecaba88c --- /dev/null +++ b/app_links/ohos/pubspec.yaml @@ -0,0 +1,84 @@ +name: app_links_ohos +description: "hap Links, Deep Links." +version: 1.0.0 +homepage: https://gitee.com/openharmony-sig/fluttertpc_app_links + +environment: +# sdk: '>=3.4.0 <4.0.0' +# flutter: '>=3.3.0' + + sdk: ^3.3.0 + flutter: ">=3.19.0" + +dependencies: + flutter: + sdk: flutter + plugin_platform_interface: ^2.0.2 + + app_links_linux: ^1.0.3 + app_links_platform_interface: ^2.0.2 + app_links_web: ^1.0.4 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^3.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) + # which should be registered in the plugin registry. This is required for + # using method channels. + # The Android 'package' specifies package in which the registered class is. + # This is required for using method channels on Android. + # The 'ffiPlugin' specifies that native code should be built and bundled. + # This is required for using `dart:ffi`. + # All these are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + ohos: + package: com.llfbandit.app_links.app_links_ohos + pluginClass: AppLinksOhosPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages + +topics: + - deeplink + - app-links + - universal-links + - custom-url-schemes + - web-to-app \ No newline at end of file diff --git a/app_links/ohos/test/app_links_ohos_test.dart b/app_links/ohos/test/app_links_ohos_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e9bad750644b765850e5c5220ed349af2d6d7e88 --- /dev/null +++ b/app_links/ohos/test/app_links_ohos_test.dart @@ -0,0 +1,29 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:app_links_ohos/app_links_ohos.dart'; +import 'package:app_links_ohos/app_links_ohos_platform_interface.dart'; +import 'package:app_links_ohos/app_links_ohos_method_channel.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +class MockAppLinksOhosPlatform + with MockPlatformInterfaceMixin + implements AppLinksOhosPlatform { + + @override + Future getPlatformVersion() => Future.value('42'); +} + +void main() { + final AppLinksOhosPlatform initialPlatform = AppLinksOhosPlatform.instance; + + test('$MethodChannelAppLinksOhos is the default instance', () { + expect(initialPlatform, isInstanceOf()); + }); + + test('getPlatformVersion', () async { + AppLinksOhos appLinksOhosPlugin = AppLinksOhos(); + MockAppLinksOhosPlatform fakePlatform = MockAppLinksOhosPlatform(); + AppLinksOhosPlatform.instance = fakePlatform; + + expect(await appLinksOhosPlugin.getPlatformVersion(), '42'); + }); +}