diff --git a/.ci.yaml b/.ci.yaml
index c5d3d3b167e71f0c5f428c8a10e7dfd31c38daae..13005c7b58beaa32850897877c099cbea8e54298 100644
--- a/.ci.yaml
+++ b/.ci.yaml
@@ -1935,10 +1935,22 @@ targets:
- name: Linux_android_emu android_defines_test
recipe: devicelab/devicelab_drone
timeout: 60
+ dimensions: {
+ kvm: "1",
+ cores: "8",
+ machine_type: "n1-standard-8"
+ }
properties:
+ device_type: "none"
tags: >
["devicelab", "linux"]
+ ["devicelab", "linux"]
task_name: android_defines_test
+ dependencies: >-
+ [
+ {"dependency": "android_virtual_device", "version": "31"}
+ ]
+ use_emulator: "true"
- name: Linux_pixel_7pro android_obfuscate_test
recipe: devicelab/devicelab_drone
diff --git a/OAT.xml b/OAT.xml
new file mode 100644
index 0000000000000000000000000000000000000000..db0de33e4814799957492b0df1699b0a167a7d5c
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README b/README
new file mode 100644
index 0000000000000000000000000000000000000000..dae9e7f450b2ed136432c4d9838481fa0b5e002f
--- /dev/null
+++ b/README
@@ -0,0 +1,29 @@
+The Dart SDK is a set of tools and libraries for the Dart programming language.
+
+You can find information about Dart online at https://dart.dev/.
+
+Here's a brief guide to what's in here:
+
+bin/ Binaries/scripts to compile, run, and manage Dart apps.
+ dart Command line Dart tool
+ dartaotruntime Minimal Dart runtime for running AOT modules
+ resources/ Resource files for dartdoc and devtools
+ snapshots/ AppAOT and AppJIT snapshots of various tools
+ utils/ Tools used by Dart compilers
+
+include/ header files that define the Dart embedding API for use by
+ - C/C++ applications that embed the Dart Virtual machine
+ - native libraries loaded into a dart application using FFI
+ (https://dart.dev/guides/libraries/c-interop)
+
+lib/ Libraries that are shipped with the Dart runtime. More
+ information is available at https://api.dart.dev.
+
+LICENSE Description of Dart SDK license
+
+README This file
+
+revision The git commit ID of the SDK build
+ (for example, 020b3efd3f0023c5db2097787f7cf778db837a8f).
+
+version The version number of the SDK (for example, 2.12.1).
diff --git a/README.OpenSource b/README.OpenSource
new file mode 100644
index 0000000000000000000000000000000000000000..fe2476c6851f98cc561f03ebda3d632089d315fe
--- /dev/null
+++ b/README.OpenSource
@@ -0,0 +1,11 @@
+[
+ {
+ "Name": "flutter",
+ "License": "BSD 3-Clause License",
+ "License File": "LICENSE",
+ "Version Number": "3.7.12",
+ "Owner": "aibin@openvalley.net",
+ "Upstream URL": "https://github.com/flutter/flutter/",
+ "Description": "Flutter makes it easy and fast to build beautiful mobile apps. Flutter is Google''s mobile app SDK for crafting high-quality native interfaces on iOS and Android in record time. Flutter works with existing code, is used by developers and organization"
+ }
+]
\ No newline at end of file
diff --git a/README.en.md b/README.en.md
new file mode 100644
index 0000000000000000000000000000000000000000..04aa77e87ac557f14d95572f00f22881a515de4c
--- /dev/null
+++ b/README.en.md
@@ -0,0 +1,326 @@
+Flutter SDK repository
+==============
+
+Original warehouse source: https://github.com/flutter/flutter
+
+## Warehouse description
+1. This repository is a compatible extension of Flutter SDK for the OpenHarmony platform, and can support IDE or terminal use of Flutter Tools instructions to compile and build OpenHarmony applications.
+2. This repository is built based on the Flutter official community version 3.22.0
+ * [sdk base version](https://github.com/flutter/flutter/commit/5dcb86f68f239346676ceb1ed1ea385bd215fba1)
+ * [engine base version](https://github.com/flutter/engine/commit/f6344b75dcf861d8bf1f1322780b8811f982e31a)
+
+## Upgrade Guide
+1. If your project is upgrading from HarmonyOS version 3.7.12 to version 3.22.0:
+ * Environment dependencies: Configuration remains consistent between the two versions, no additional modifications required.
+ * For new features and changes from 3.7.12 to 3.22.0, please refer to the [Release Notes](https://docs.flutter.dev/release/release-notes).
+ * For official compatibility changes, please refer to the [Upgrade Guide](https://docs.flutter.dev/release/breaking-changes).
+ * Rendering Engine: Added impeller-vulkan mode (default, can be switched to skia-gl).
+ * Third-party libraries:
+ - Pure Dart libraries should be upgraded to the specified version to support 3.22.0.
+ - The packages in [OpenHarmony-SIG/flutter_packages](https://gitee.com/openharmony-sig/flutter_packages/blob/master/README.md) have undergone a basic usability test for version 3.22.0. If you encounter any issues during use, please create an issue for tracking.
+2. If your project is migrating from Android or iOS to the HarmonyOS adaptation for version 3.22.0, please refer to the remaining guide documents.
+
+## Development document
+[Docs](https://gitee.com/openharmony-sig/flutter_samples/tree/master/ohos/docs)
+
+## Environment dependencies
+
+* development system
+
+ Flutter Tools commands are currently supported on Linux, Mac and Windows.
+
+* Environment configuration
+
+ **Please download the supporting development tool from [OpenHarmony SDK](https://developer.huawei.com/consumer/cn/develop)**
+ *The following environment variable configuration is for Unix-like systems (Linux, Mac). You can directly refer to the configuration below. For environment variable configuration under Windows, please set it in ‘Edit System Environment Variables’*
+
+ 1. Configure the HarmonyOS SDK and environment variables
+ * API12, deveco-studio-5.0 or command-line-tools-5.0 (Recommended to use version 5.0.0 Release or later)
+ * Configure Java17
+ * Configure environment variables (SDK, node, ohpm, hvigor)
+
+ ```sh
+ export TOOL_HOME=/Applications/DevEco-Studio.app/Contents # For mac
+ export DEVECO_SDK_HOME=$TOOL_HOME/sdk # command-line-tools/sdk
+ export PATH=$TOOL_HOME/tools/ohpm/bin:$PATH # command-line-tools/ohpm/bin
+ export PATH=$TOOL_HOME/tools/hvigor/bin:$PATH # command-line-tools/hvigor/bin
+ export PATH=$TOOL_HOME/tools/node/bin:$PATH # command-line-tools/tool/node/bin
+ ```
+
+ 2. Download the current warehouse code `git clone https://gitee.com/openharmony-sig/flutter_flutter.git` Specify the dev or master branch and configure the environment
+
+ ```sh
+ export PATH=/bin:$PATH
+ export PUB_CACHE=D:/PUB
+ # Domestic mirror
+ export PUB_HOSTED_URL=https://pub.flutter-io.cn
+ export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
+ ```
+
+ 3. becomes an optional parameter and may not be passed.
+ - Usage example: `--local-engine=src/out/`
+ - You can download [compiled product](https://docs.qq.com/sheet/DUnljRVBYUWZKZEtF?tab=BB08J2) from this path.
+ - The engine path points to the directory that needs to be accompanied by 'src/out'.
+
+ For the configuration of all the above environment variables (for environment variable configuration under Windows, please set it in 'Edit System Environment Variables'), you can refer to the following example (please replace user and specific code path with the actual path):
+
+ ```sh
+ # Dependent cache
+ export PUB_CACHE=D:/PUB(Custom path)
+
+ # Domestic mirror
+ export PUB_HOSTED_URL=https://pub.flutter-io.cn
+ export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
+
+ # The flutter_flutter directory pulled from Gitee
+ export PATH=/home//ohos/flutter_flutter/bin:$PATH
+
+ # HarmonyOS SDK
+ export TOOL_HOME=/Applications/DevEco-Studio.app/Contents # For mac
+ export DEVECO_SDK_HOME=$TOOL_HOME/sdk # command-line-tools/sdk
+ export PATH=$TOOL_HOME/tools/ohpm/bin:$PATH # command-line-tools/ohpm/bin
+ export PATH=$TOOL_HOME/tools/hvigor/bin:$PATH # command-line-tools/hvigor/bin
+ export PATH=$TOOL_HOME/tools/node/bin:$PATH # command-line-tools/tool/node/bin
+ ```
+
+## Build steps
+
+1. Run `flutter doctor -v` to check whether the environment variable configuration is correct. **Futter** and **OpenHarmony** should both be ok. If the two prompts indicate that the environment is missing, just follow the prompts to fill in the corresponding environment.
+
+2. Create the project and compile the command. The compiled product is under \/ohos/entry/build/default/outputs/default/entry-default-signed.hap.
+
+ ```
+ # Create project
+ flutter create --platforms ohos
+
+ # Go to the project root directory for compilation
+ # Example: flutter build hap [--target-platform ohos-arm64] --local-engine=/src/out/ohos_release_arm64 --release
+ flutter build hap --target-platform ohos-arm64 -- --local-engine=/src/out/ --local-engine-host=src/out//
+ ```
+ 2.1 Create a Project and Enable the Impeller
+ Currently, the Flutter OHOS platform supports the impeller-vulkan rendering mode, which can be controlled via a switch. The switch is located in the 'buildinfo.json5' file. If you choose to disable the Impeller rendering, you can change the value in the JSON file to false. The next time you run the project, the Impeller will be disabled.
+ File path: `ohos/entry/src/main/resources/rawfile/buildinfo.json5`
+ (After the initial `flutter create`, the configuration file is located in the `profile` directory. After the first `run` or `build`, it will be moved to the `rawfile` directory.)
+
+ File content:
+ ```json
+ {
+ "string": [
+ {
+ "name": "enable_impeller",
+ "value": "true"
+ }
+ ]
+ }
+ ```
+ By default, the Impeller option is enabled in new projects.
+ For existing projects, you can copy the above buildinfo.json5 file to the corresponding directory(rawfile) in your project and modify the value to enable or disable the switch. If the switch does not exist, then will set enable-impeller by default.
+
+3. After discovering the ohos device through the `flutter devices` command, use `hdc -t install ` to install it.
+
+4. You can also directly use the following command to run:
+ ```
+ # Example: flutter run [--local-engine=/src/out/ohos_debug_unopt_arm64] [--local-engine-host=/src/out/host_debug_unopt] -d
+ flutter run --debug -d
+ ```
+
+5. Build app package command:
+ ```
+ # Example: flutter run --local-engine=/src/out/ohos_debug_unopt_arm64 -d
+ flutter run --debug --local-engine=/home/user/engine_make/src/out/ohos_debug_unopt_arm64 -d --local-engine-host=src/out//
+ ```
+
+## Release Notes
+ - [3.22.0-ohos-0.1.0 Beta](/release-notes/Flutter%203.22.0-ohos%200.1.0%20ReleaseNote.en.md)
+
+## Compatible command list developed by OpenHarmony
+
+| Command name | Command description | Instructions for use |
+| ------- | ------- |-------------------------------------------------------------------|
+| doctor | environment detection | flutter doctor |
+| config | environment configuration | flutter config --\ \ |
+| create | Create a new project | flutter create --platforms ohos,android,ios --org \ \ |
+| create | Create module template | flutter create -t module \ |
+| create | Create plugin template | flutter create -t plugin --platforms ohos,android,ios \ |
+| create | Create plugin_ffi template | flutter create -t plugin_ffi --platforms ohos,android,ios \ |
+| devices | Connected device discovery | flutter devices |
+| install | application installation | flutter install -t \ \ |
+| assemble | resource packaging | flutter assemble |
+| build | Test application build | flutter build hap --debug [--target-platform ohos-arm64] [--local-engine=\] |
+| build | Formal application build | flutter build hap --release [--target-platform ohos-arm64] [--local-engine=\] |
+| run | application run | flutter run [--local-engine=\] |
+| attach | debug mode | flutter attach |
+| screenshot | screenshot | flutter screenshot |
+| pub | Obtains the dependencies.| flutter pub get |
+| clean | Clears the project dependencies.| flutter clean |
+| cache | Clears global cache data.| flutter pub cache clean |
+
+Attachment: [Flutter third-party library adaptation plan](https://docs.qq.com/sheet/DVVJDWWt1V09zUFN2)
+
+## Common Problem
+
+1. After switching to FLUTTER_STORAGE_BASE_URL, you need to delete the \/bin/cache directory and execute Flutter clean in the project before running it again.
+
+2. If an error message appears: `The SDK license agreement is not accepted`, please execute the following command and compile again:
+
+ ```
+ ./ohsdkmgr install ets:9 js:9 native:9 previewer:9 toolchains:9 --sdk-directory='/home/xc/code/sdk/ohos-sdk/' --accept-license
+ ```
+
+3. If you are using the Beta version of DevEco Studio and encounter the error "must have required property 'compatibleSdkVersion', location: demo/ohos/build-profile.json5:17:11" when compiling the project, Modify the hvigor/hvigor-config.json5 file by referring to section ‘6 Create the project and run Hello World’ [Configuration Plug-in] in《DevEco Studio Environment configuration guide.docx》.
+
+4. If you are prompted with an installation error: `fail to verify pkcs7 file`, please execute the command
+
+ ```
+ hdc shell param set persist.bms.ohCert.verify true
+ ```
+5. Linux virtual machine cannot directly discover OpenHarmony devices through hdc
+
+ Solution: In the Windows host, open the hdc server. The specific instructions are as follows:
+ ```
+ hdc kill
+ hdc -s serverIP:8710 -m
+ ```
+ Configure environment variables in linux:
+ ```
+ HDC_SERVER=
+ HDC_SERVER_PORT=8710
+ ```
+
+ After the configuration is completed, the flutter sdk can complete the device connection through the hdc server. You can also refer to [official guidance](https://docs.openharmony.cn/pages/v4.0/zh-cn/device-dev/subsystems/subsys-toolchain -hdc-guide.md/#hdc-client%E5%A6%82%E4%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AEhdc-server) .
+
+6. An error occurred when building the Hap task: Error: The hvigor depends on the npmrc file. Configure the npmrc file first.
+
+
+ Please create the file `.npmrc` in the user directory `~`. For this configuration, please refer to [DevEco Studio official documentation](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/environment_config -0000001052902427-V3), the edited content is as follows:
+
+ ```
+ registry=https://repo.huaweicloud.com/repository/npm/
+ @ohos:registry=https://repo.harmonyos.com/npm/
+ ```
+7. Symptom Logs are lost during log query。
+ Solution:Disable global logs and enable only logs in your domain
+
+ ```
+ Step one:Disable log printing for all fields(Some special logs cannot be closed)
+ hdc shell hilog -b X
+ Step two:Open logs for your domain only
+ hdc shell hilog -D
+ indicates the level of log printing:D/I/W/E/F,is the number before the Tag
+ Example:
+ To print logs about 'A00000/XComFlutterOHOS_Native', set 'hdc shell hilog -b D -D A00000'
+ annotation:The above Settings will be invalid after the machine is restarted, and you need to reset them if you want to continue using them
+ ```
+8. If the debug signature application cannot be started on API 11BETA1, it can be resolved by changing the signature to an official signature or opening the developer mode on the mobile terminal (steps: Settings -> General -> Developer mode).
+
+9. If `Invalid CEN header (invalid zip64 extra data field size)` is abnormal, please replace the JDK version, see [JDK-8313765]
+
+10. An error occurs when running a debug version of the Flutter application on a HarmonyOS device (release and profile versions are normal)
+ 1. Error message: `Error while initializing the Dart VM: Wrong full snapshot version, expected '8af474944053df1f0a3be6e6165fa7cf' found 'adb4292f3ec25074ca70abcd2d5c7251'`
+ 2. Solution: Perform the following actions in sequence
+ 1. Set environment variables `export FLUTTER_STORAGE_BASE_URL=https://flutter-ohos.obs.cn-south-1.myhuaweicloud.com`
+ 1. Delete the cache in the/bin/cache directory
+ 2. Execute `fluent clean` to clear the project compilation cache
+ 3. Execute `flutter run -d $DEVICE --debug`
+ 3. Additional information: If a similar error occurs while running Android or iOS, you can also try restoring the environment variable FLUTTER_STORAGE_BASE_URL , clearing the cache, and then running again.
+
+11. After the ROM update of Beta 2 version, it no longer supports requesting anonymous memory with execution permission, resulting in debug crashing.
+ 1. Solution: Update flutter_flutter to a version after a44b8a6d (2024-07-25).
+ 2. Key logs:
+
+ ```
+ #20 at attachToNative (oh_modules/.ohpm/@ohos+flutter_ohos@g8zhdaqwu8gotysbmqcstpfpcpy=/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets:78:32)
+ #21 at attachToNapi (oh_modules/.ohpm/@ohos+flutter_ohos@g8zhdaqwu8gotysbmqcstpfpcpy=/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets:144:5)
+ #22 at init (oh_modules/.ohpm/@ohos+flutter_ohos@g8zhdaqwu8gotysbmqcstpfpcpy=/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets:133:7)
+ ```
+
+12. Build Hap command directly execute `flutter build hap`, no longer need `--local-engine` parameter, directly from the cloud to obtain the compilation product
+
+13. After the environment is configured, the system crashes when the flutter command is executed。
+ 1. Solution:Add git environment variable configuration in windows environment。
+ ```
+ export PATH=/cmd:$PATH
+ ```
+
+14. If `flutter pub cache clean` is executed normally, `flutter clean` will report an error. If update command is executed according to the error message, it has no effect。
+ 1. Solution:To avoid this problem, comment out the configuration in the build.json5 file。
+ 2. Error message:
+ ```
+ #Parse ohos module. json5 error: Exception: Can not found module.json5 at
+ #D:\pub_cache\git\flutter_packages-b00939bb44d018f0710d1b080d91dcf4c34ed06\packages\video_player\video_player_ohos\ohossrc\main\module.json5.
+ #You need to update the Flutter plugin project structure.
+ #See
+ #https://gitee.com/openharmony-sig/flutter_samples/tree/master/ohos/docs/09_specifications/update_flutter_plugin_structure.md
+ ```
+
+15. An error message indicating path verification occurs when `flutter build hap` is executed。
+ 1. Solution:
+ · Open the ohos-project-build-profile-schema.json file in deveco installation path D:\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\res\schemas。
+ · Find the line containing: "pattern": "^(\\./|\\.\\./)[\\s\\S]+$" in the file and delete it。
+ 2. Error message:
+ ```
+ #hvigor ERROR: Schema validate failed.
+ # Detail: Please check the following fields.
+ #instancePath: 'modules[1].scrPath',
+ #keyword: 'pattern'
+ #params: { pattern:'^(\\./|\\.\\./)[\\s\\S]+$' },
+ #message: 'must match pattern "^(\\./|\\.\\./)[\\s\\S]+$"',
+ #location: 'D:/work/videoplayerdemo/video_cannot_stop_at_background/ohos/build-profile.json:42:146'
+ ```
+
+16. Execute `flutter build hap` report an error。
+ 1. Solution:Open the core-module-model-impl.js file in deveco installation path D:\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\src\model\module。,
+ Modify the findBelongProjectPath method (requires administrator rights, can be saved as and replaced)
+ ```
+ findBelongProjectPath(e) {
+ if (e === path_1.default.dirname(e)) {
+ return this.parentProject.getProjectDir()
+ }
+ }
+ ```
+ 2. Error message:
+ ```
+ # hvigor ERROR: Cannot find belonging project path for module at D:\.
+ # hvigor ERROR: BUILD FAILED in 2s 556ms.
+ #Running Hvigor task assembleHap...
+ #Oops; flutter has exited unexpectedly: "ProcessException: The command failed
+ #
-
-
-
-
-
-
-
-
-[](https://flutter-dashboard.appspot.com/#/build?repo=flutter)
-[![Discord badge][]][Discord instructions]
-[![Twitter handle][]][Twitter badge]
-[](https://codecov.io/gh/flutter/flutter)
-[](https://bestpractices.coreinfrastructure.org/projects/5631)
-[](https://deps.dev/project/github/flutter%2Fflutter)
-[](https://slsa.dev)
-
-Flutter is Google's SDK for crafting beautiful, fast user experiences for
-mobile, web, and desktop from a single codebase. Flutter works with existing
-code, is used by developers and organizations around the world, and is free and
-open source.
-
-## Documentation
-
-* [Install Flutter](https://flutter.dev/get-started/)
-* [Flutter documentation](https://docs.flutter.dev/)
-* [Development wiki](https://github.com/flutter/flutter/wiki)
-* [Contributing to Flutter](https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md)
-
-For announcements about new releases, follow the
-[flutter-announce@googlegroups.com](https://groups.google.com/forum/#!forum/flutter-announce)
-mailing list. Our documentation also tracks [breaking
-changes](https://docs.flutter.dev/release/breaking-changes) across releases.
-
-## Terms of service
-
-The Flutter tool may occasionally download resources from Google servers. By
-downloading or using the Flutter SDK, you agree to the Google Terms of Service:
-https://policies.google.com/terms
-
-For example, when installed from GitHub (as opposed to from a prepackaged
-archive), the Flutter tool will download the Dart SDK from Google servers
-immediately when first run, as it is used to execute the `flutter` tool itself.
-This will also occur when Flutter is upgraded (e.g. by running the `flutter
-upgrade` command).
-
-## About Flutter
-
-We think Flutter will help you create beautiful, fast apps, with a productive,
-extensible and open development model, whether you're targeting iOS or Android,
-web, Windows, macOS, Linux or embedding it as the UI toolkit for a platform of
-your choice.
-
-### Beautiful user experiences
-
-We want to enable designers to deliver their full creative vision without being
-forced to water it down due to limitations of the underlying framework.
-Flutter's [layered architecture] gives you control over every pixel on the
-screen and its powerful compositing capabilities let you overlay and animate
-graphics, video, text, and controls without limitation. Flutter includes a full
-[set of widgets][widget catalog] that deliver pixel-perfect experiences whether
-you're building for iOS ([Cupertino]) or other platforms ([Material]), along with
-support for customizing or creating entirely new visual components.
-
-
-
-### Fast results
-
-Flutter is fast. It's powered by hardware-accelerated 2D graphics
-libraries like [Skia] (that underpins Chrome and Android) and
-[Impeller]. We architected Flutter to
-support glitch-free, jank-free graphics at the native speed of your device.
-
-Flutter code is powered by the world-class [Dart platform], which enables
-compilation to 32-bit and 64-bit ARM machine code for iOS and Android,
-JavaScript and WebAssembly for the web, as well as Intel x64 and ARM
-for desktop devices.
-
-
-
-### Productive development
-
-Flutter offers [stateful hot reload][Hot reload], allowing you to make changes to your code
-and see the results instantly without restarting your app or losing its state.
-
-[![Hot reload animation][]][Hot reload]
-
-### Extensible and open model
-
-Flutter works with any development tool (or none at all), and also includes
-editor plug-ins for both [Visual Studio Code] and [IntelliJ / Android Studio].
-Flutter provides [tens of thousands of packages][Flutter packages] to speed your
-development, regardless of your target platform. And accessing other native code
-is easy, with support for both FFI ([on Android][Android FFI], [on iOS][iOS FFI],
-[on macOS][macOS FFI], and [on Windows][Windows FFI]) as well as
-[platform-specific APIs][platform channels].
-
-Flutter is a fully open-source project, and we welcome contributions.
-Information on how to get started can be found in our
-[contributor guide](CONTRIBUTING.md).
-
-[flutter.dev]: https://flutter.dev
-[Discord instructions]: https://github.com/flutter/flutter/wiki/Chat
-[Discord badge]: https://img.shields.io/discord/608014603317936148?logo=discord
-[Twitter handle]: https://img.shields.io/twitter/follow/flutterdev.svg?style=social&label=Follow
-[Twitter badge]: https://twitter.com/intent/follow?screen_name=flutterdev
-[layered architecture]: https://docs.flutter.dev/resources/inside-flutter
-[architectural overview]: https://docs.flutter.dev/resources/architectural-overview
-[widget catalog]: https://flutter.dev/widgets/
-[Cupertino]: https://docs.flutter.dev/development/ui/widgets/cupertino
-[Material]: https://docs.flutter.dev/development/ui/widgets/material
-[Skia]: https://skia.org/
-[Dart platform]: https://dart.dev/
-[Hot reload animation]: https://github.com/flutter/website/blob/main/src/assets/images/docs/tools/android-studio/hot-reload.gif?raw=true
-[Hot reload]: https://docs.flutter.dev/development/tools/hot-reload
-[Visual Studio Code]: https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
-[IntelliJ / Android Studio]: https://plugins.jetbrains.com/plugin/9212-flutter
-[Flutter packages]: https://pub.dev/flutter
-[Android FFI]: https://docs.flutter.dev/development/platform-integration/android/c-interop
-[iOS FFI]: https://docs.flutter.dev/development/platform-integration/ios/c-interop
-[macOS FFI]: https://docs.flutter.dev/development/platform-integration/macos/c-interop
-[Windows FFI]: https://docs.flutter.dev/development/platform-integration/windows/building#integrating-with-windows
-[platform channels]: https://docs.flutter.dev/development/platform-integration/platform-channels
-[interop example]: https://github.com/flutter/flutter/tree/master/examples/platform_channel
-[Impeller]: https://docs.flutter.dev/perf/impeller
+Flutter SDK 仓库
+==============
+
+原始仓来源:https://github.com/flutter/flutter
+
+## 仓库说明
+1. 本仓库是基于Flutter SDK对于OpenHarmony平台的兼容拓展,可支持IDE或者终端使用Flutter Tools指令编译和构建OpenHarmony应用程序。
+2. 本仓库基于Flutter官方社区3.22.0版本构建
+ * [sdk基础版本链接](https://github.com/flutter/flutter/commit/5dcb86f68f239346676ceb1ed1ea385bd215fba1)
+ * [engine基础版本链接](https://github.com/flutter/engine/commit/f6344b75dcf861d8bf1f1322780b8811f982e31a)
+
+## 升级指导
+1. 如果您的项目希望从鸿蒙3.7.12版本升级到3.22.0版本
+ * 环境依赖:两者环境配置一致,无需额外修改
+ * 从3.7.12->3.22.0的官方特性新增与变更请参考[Release Notes](https://docs.flutter.dev/release/release-notes)
+ * 官方兼容性变更请参考[升级指导](https://docs.flutter.dev/release/breaking-changes)
+ * 渲染引擎:新增impeller-vulkan模式(默认,可切换为skia-gl)
+ * 三方库
+ - 纯dart库请升级到指定版本以支持3.22.0
+ - [OpenHarmony-SIG/flutter_packages](https://gitee.com/openharmony-sig/flutter_packages/blob/master/README.md)中的package在3.22.0版本已经过一轮简单的可用性测试,如果在您使用中有任何问题,烦请创建issue跟踪解决。
+
+2. 如果您的项目希望从安卓或ios等版本迁移到鸿蒙适配3.22.0版本,请参考剩余指导文档。
+
+## 开发文档
+[参考文档](https://gitee.com/openharmony-sig/flutter_samples/tree/master/ohos/docs)
+
+## 环境依赖
+
+* 开发系统
+
+ Flutter Tools指令目前已支持在Linux、Mac和Windows下使用。
+
+* 环境配置
+ **请从[鸿蒙SDK](https://developer.huawei.com/consumer/cn/develop)下载配套开发工具**
+ *下列环境变量配置,类Unix系统(Linux、Mac),下可直接参照配置,Windows下环境变量配置请在‘编辑系统环境变量’中设置*
+
+ 1. 配置HarmonyOS SDK和环境变量
+ * API12, deveco-studio-5.0 或 command-line-tools-5.0 (推荐使用5.0.0 Release或更新版本)
+ * 配置 Java17
+ * 配置环境变量 (SDK, node, ohpm, hvigor)
+
+ ```sh
+ export TOOL_HOME=/Applications/DevEco-Studio.app/Contents # mac环境
+ export DEVECO_SDK_HOME=$TOOL_HOME/sdk # command-line-tools/sdk
+ export PATH=$TOOL_HOME/tools/ohpm/bin:$PATH # command-line-tools/ohpm/bin
+ export PATH=$TOOL_HOME/tools/hvigor/bin:$PATH # command-line-tools/hvigor/bin
+ export PATH=$TOOL_HOME/tools/node/bin:$PATH # command-line-tools/tool/node/bin
+ ```
+
+ 2. 通过代码工具下载当前仓库代码`git clone https://gitee.com/openharmony-sig/flutter_flutter.git`,指定dev或master分支,并配置环境
+
+ ```sh
+ export PUB_CACHE=D:/PUB
+ export PATH=/bin:$PATH
+ export PUB_HOSTED_URL=https://pub.flutter-io.cn
+ export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
+ ```
+
+ 3. 应用构建依赖flutter engine构建产物与engine host,默认从云端获取。也可以手工指定
+ - 使用示例:`--local-engine=src/out/ --local-engine-host=src/our/`
+ 均在 `src/out` 路径下。不同构建类型的产物分别在 `ohos_debug_unopt_arm64`、 `ohos_release_arm64` 和 `ohos_profile_arm64` 目录下。engine host 的构建类型也有三种,分别在 `host_debug_unopt` 、`host_release` 与 `host_profile` 目录中。构建需要根据不同的构建类型来指定不同的目录。
+
+ ```sh
+ #依赖缓存
+ export PUB_CACHE=D:/PUB(自定义路径)
+
+ # 国内镜像
+ export PUB_HOSTED_URL=https://pub.flutter-io.cn
+ export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
+
+ # 拉取下来的flutter_flutter/bin目录
+ export PATH=/home//ohos/flutter_flutter/bin:$PATH
+
+ # HamonyOS SDK
+ export TOOL_HOME=/Applications/DevEco-Studio.app/Contents # mac环境
+ export DEVECO_SDK_HOME=$TOOL_HOME/sdk # command-line-tools/sdk
+ export PATH=$TOOL_HOME/tools/ohpm/bin:$PATH # command-line-tools/ohpm/bin
+ export PATH=$TOOL_HOME/tools/hvigor/bin:$PATH # command-line-tools/hvigor/bin
+ export PATH=$TOOL_HOME/tools/node/bin:$PATH # command-line-tools/tool/node/bin
+ ```
+
+## 构建步骤
+
+1. 运行 `flutter doctor -v` 检查环境变量配置是否正确,**Futter**与**OpenHarmony**应都为ok标识,若两处提示缺少环境,按提示补上相应环境即可。
+
+2. 创建工程与编译命令,编译产物在\/ohos/entry/build/default/outputs/default/entry-default-signed.hap下。
+
+ ```
+ # 创建工程
+ flutter create --platforms ohos
+
+ # 进入工程根目录编译
+ # 示例:flutter build hap [--target-platform ohos-arm64] [--local-engine=/src/out/ohos_release_arm64] --release
+ flutter build hap --target-platform ohos-arm64 -- [--local-engine=src/out/ --local-engine-host=src/out//]
+ ```
+ 2.1 创建工程并打开impeller开关
+ 当前Flutter ohos平台中支持impeller-vulkan渲染模式,可通过开关控制是否打开。
+ 开关位于`buildinfo.json5`文件中,如果选择关闭impeller渲染,可将json文件中的value改为false。下一次运行时即可关闭。
+ 文件路径:`ohos/entry/src/main/resources/rawfile/buildinfo.json5`
+ (初次flutter create之后,配置文件位于profile目录,首次run或build之后会搬移到rawfile目录)
+
+ 文件内容:
+ ```json
+ {
+ "string": [
+ {
+ "name": "enable_impeller",
+ "value": "true"
+ }
+ ]
+ }
+ ```
+ 新建工程默认打开impeller选项。
+ 对于旧工程,可将以上buildinfo.json5文件复制到工程目录的对应路径下(rawfile目录),并修改value值即可实现开关功能。如果不添加开关,则默认打开enable-impeller。
+
+3. 通过`flutter devices`指令发现ohos设备之后,使用 `hdc -t install `进行安装。
+
+4. 也可直接使用下列指令运行:
+```
+ flutter run --debug [--local-engine=/src/out/ohos_debug_unopt_arm64] [--local-engine-host=/src/out/host_debug_unopt] -d
+```
+
+5. 构建app包命令:
+ ```
+ # 示例:flutter build app --release [--local-engine=/src/out/ohos_release_arm64] [--local-engine-host=/src/out/host_release]
+ flutter build app --release
+ ```
+
+## 版本说明
+ - [3.22.0-ohos-0.1.0 Beta](/release-notes/Flutter%203.22.0-ohos%200.1.0%20ReleaseNote.md)
+
+## 已兼容OpenHarmony开发的指令列表
+| 指令名称 | 指令描述 | 使用说明 |
+| ------- | ------- |-------------------------------------------------------------------|
+| doctor | 环境检测 | flutter doctor |
+| config | 环境配置 | flutter config --\ \ |
+| create | 创建新项目 | flutter create --platforms ohos,android,ios --org \ \ |
+| create | 创建module模板 | flutter create -t module \ |
+| create | 创建plugin模板 | flutter create -t plugin --platforms ohos,android,ios \ |
+| create | 创建plugin_ffi模板 | flutter create -t plugin_ffi --platforms ohos,android,ios \ |
+| devices | 已连接设备查找 | flutter devices |
+| install | 应用安装 | flutter install -t \ \ |
+| assemble | 资源打包 | flutter assemble |
+| build | 测试应用构建 | flutter build hap --debug [--target-platform ohos-arm64] [--local-engine=\<兼容ohos的debug engine产物路径\>] |
+| build | 正式应用构建 | flutter build hap --release [--target-platform ohos-arm64] [--local-engine=\<兼容ohos的release engine产物路径\>] |
+| run | 应用运行 | flutter run [--local-engine=\<兼容ohos的engine产物路径\>] |
+| attach | 调试模式 | flutter attach |
+| screenshot | 截屏 | flutter screenshot |
+| pub | 获取依赖 | flutter pub get |
+| clean | 清除项目依赖 | flutter clean |
+| cache | 清除全局缓存数据 | flutter pub cache clean |
+
+附:[Flutter三方库适配计划](https://docs.qq.com/sheet/DVVJDWWt1V09zUFN2)
+
+
+## 常见问题
+
+1. 切换FLUTTER_STORAGE_BASE_URL后需删除\/bin/cache 目录,并在项目中执行flutter clean后再运行
+
+2. 若出现报错:`The SDK license agreement is not accepted`,参考执行以下命令后再次编译:
+
+ ```
+ ./ohsdkmgr install ets:9 js:9 native:9 previewer:9 toolchains:9 --sdk-directory='/home/xc/code/sdk/ohos-sdk/' --accept-license
+ ```
+
+3. 如果你使用的是DevEco Studio的Beta版本,编译工程时遇到“must have required property 'compatibleSdkVersion', location: demo/ohos/build-profile.json5:17:11"错误,请参考《DevEco Studio环境配置指导.docx》中的‘6 创建工程和运行Hello World’【配置插件】章节修改 hvigor/hvigor-config.json5文件。
+
+4. 若提示安装报错:`fail to verify pkcs7 file` 请执行指令
+
+ ```
+ hdc shell param set persist.bms.ohCert.verify true
+ ```
+5. linux虚拟机通过hdc无法直接发现OpenHarmony设备
+
+ 解决方案:在windows宿主机中,开启hdc server,具体指令如下:
+ ```
+ hdc kill
+ hdc -s serverIP:8710 -m
+ ```
+ 在linux中配置环境变量:
+ ```
+ HDC_SERVER=
+ HDC_SERVER_PORT=8710
+ ```
+
+ 配置完成后flutter sdk可以通过hdc server完成设备连接,也可参考[官方指导](https://docs.openharmony.cn/pages/v4.0/zh-cn/device-dev/subsystems/subsys-toolchain-hdc-guide.md/#hdc-client%E5%A6%82%E4%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BF%E9%97%AEhdc-server)。
+
+6. 构建Hap任务时报错:Error: The hvigor depends on the npmrc file. Configure the npmrc file first.
+
+
+ 请在用户目录`~`下创建文件`.npmrc`,该配置也可参考[DevEco Studio官方文档](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/environment_config-0000001052902427-V3),编辑内容如下:
+
+ ```
+ registry=https://repo.huaweicloud.com/repository/npm/
+ @ohos:registry=https://repo.harmonyos.com/npm/
+ ```
+
+7. 查日志时,存在日志丢失现象。
+ 解决方案:关闭全局日志,只打开自己领域的日志
+
+ ```
+ 步骤一:关闭所有领域的日志打印(部分特殊日志无法关闭)
+ hdc shell hilog -b X
+ 步骤二:只打开自己领域的日志
+ hdc shell hilog -D
+ 其中为日志打印的级别:D/I/W/E/F,为Tag前面的数字
+ 举例:
+ 打印A00000/XComFlutterOHOS_Native的日志,需要设置hdc shell hilog -b D -D A00000
+ 注:上面的设置在机器重启后会失效,如果要继续使用,需要重新设置。
+ ```
+8. 若Api11 Beta1版本的机器上无法启动debug签名的应用,可以通过将签名换成正式签名,或在手机端打开开发者模式解决(步骤:设置->通用->开发者模式)
+
+9. 如果报`Invalid CEN header (invalid zip64 extra data field size)`异常,请更换Jdk版本,参见[JDK-8313765](https://bugs.openjdk.org/browse/JDK-8313765)
+
+10. 运行debug版本的flutter应用用到鸿蒙设备后报错(release和profile版本正常)
+ 1. 报错信息: `Error while initializing the Dart VM: Wrong full snapshot version, expected '8af474944053df1f0a3be6e6165fa7cf' found 'adb4292f3ec25074ca70abcd2d5c7251'`
+ 2. 解决方案: 依次执行以下操作
+ 1. 设置环境变量 `export FLUTTER_STORAGE_BASE_URL=https://flutter-ohos.obs.cn-south-1.myhuaweicloud.com`
+ 2. 删除 /bin/cache 目录下的缓存
+ 3. 执行 `flutter clean`,清除项目编译缓存
+ 4. 运行 `flutter run -d $DEVICE --debug`
+ 3. 补充信息: 运行android或ios出现类似错误,也可以尝试还原环境变量 FLUTTER_STORAGE_BASE_URL ,清除缓存后重新运行。
+
+11. Beta2版本的ROM更新后,不再支持申请有执行权限的匿名内存,导致debug运行闪退。
+ 1. 解决方案:更新 flutter_flutter 到 a44b8a6d (2024-07-25) 之后的版本。
+ 2. 关键日志:
+
+ ```
+ #20 at attachToNative (oh_modules/.ohpm/@ohos+flutter_ohos@g8zhdaqwu8gotysbmqcstpfpcpy=/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets:78:32)
+ #21 at attachToNapi (oh_modules/.ohpm/@ohos+flutter_ohos@g8zhdaqwu8gotysbmqcstpfpcpy=/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets:144:5)
+ #22 at init (oh_modules/.ohpm/@ohos+flutter_ohos@g8zhdaqwu8gotysbmqcstpfpcpy=/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets:133:7)
+ ```
+
+12. 构建Hap命令直接执行`flutter build hap`即可,不再需要`--local-engine`参数,直接从云端获取编译产物。
+
+13. 配置环境完成后执行 flutter 命令 出现闪退。
+ 1. 解决方案:windows环境中添加git环境变量配置。
+ ```
+ export PATH=/cmd:$PATH
+ ```
+
+14. 执行`flutter pub cache clean` 正常 执行`flutter clean` 报错,按照报错信息执行 update 命令也没有效果。
+ 1. 解决方案:通过注释掉 build.json5 文件中的配置规避。
+ 2. 报错信息:
+ ```
+ #Parse ohos module. json5 error: Exception: Can not found module.json5 at
+ #D:\pub_cache\git\flutter_packages-b00939bb44d018f0710d1b080d91dcf4c34ed06\packages\video_player\video_player_ohos\ohossrc\main\module.json5.
+ #You need to update the Flutter plugin project structure.
+ #See
+ #https://gitee.com/openharmony-sig/flutter_samples/tree/master/ohos/docs/09_specifications/update_flutter_plugin_structure.md
+ ```
+
+15. 执行`flutter build hap` 时遇到路径校验报错。
+ 1. 解决方案:
+ ·打开 deveco 安装路径 D:\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\res\schemas 下的 ohos-project-build-profile-schema.json文件。
+ ·在该文件中找到包含:"pattern": "^(\\./|\\.\\./)[\\s\\S]+$"的行,并删除此行。
+ 2. 报错信息:
+ ```
+ #hvigor ERROR: Schema validate failed.
+ # Detail: Please check the following fields.
+ #instancePath: 'modules[1].scrPath',
+ #keyword: 'pattern'
+ #params: { pattern:'^(\\./|\\.\\./)[\\s\\S]+$' },
+ #message: 'must match pattern "^(\\./|\\.\\./)[\\s\\S]+$"',
+ #location: 'D:/work/videoplayerdemo/video_cannot_stop_at_background/ohos/build-profile.json:42:146'
+ ```
+
+16. 执行`flutter build hap` 报错。
+ 1. 解决方案:打开 deveco 安装路径 D:\DevEco Studio\tools\hvigor\hvigor-ohos-plugin\src\model\module 下的 core-module-model-impl.js,
+ 修改 findBelongProjectPath 方法(需要管理员权限,可另存为后替换)
+ ```
+ findBelongProjectPath(e) {
+ if (e === path_1.default.dirname(e)) {
+ return this.parentProject.getProjectDir()
+ }
+ }
+ ```
+ 2. 报错信息:
+ ```
+ # hvigor ERROR: Cannot find belonging project path for module at D:\.
+ # hvigor ERROR: BUILD FAILED in 2s 556ms.
+ #Running Hvigor task assembleHap...
+ #Oops; flutter has exited unexpectedly: "ProcessException: The command failed
+ # {
+ 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/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90
--- /dev/null
+++ b/dev/benchmarks/complex_layout/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/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02
--- /dev/null
+++ b/dev/benchmarks/complex_layout/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/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/module.json5 b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96
--- /dev/null
+++ b/dev/benchmarks/complex_layout/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/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/element/color.json b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/dev/benchmarks/complex_layout/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/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/element/string.json b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c
--- /dev/null
+++ b/dev/benchmarks/complex_layout/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/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/media/icon.png b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/media/icon.png differ
diff --git a/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe
--- /dev/null
+++ b/dev/benchmarks/complex_layout/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "testability/pages/Index"
+ ]
+}
diff --git a/dev/benchmarks/complex_layout/ohos/hvigor/hvigor-config.json5 b/dev/benchmarks/complex_layout/ohos/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..541ba35711b75986f9295410ee38fdb8f2572878
--- /dev/null
+++ b/dev/benchmarks/complex_layout/ohos/hvigor/hvigor-config.json5
@@ -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.
+*/
+
+{
+ "modelVersion": "5.0.0",
+ "dependencies": {
+ }
+}
\ No newline at end of file
diff --git a/dev/benchmarks/complex_layout/ohos/hvigorfile.ts b/dev/benchmarks/complex_layout/ohos/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8f2d2aafe6d6a3a71a9944ebd0c91fbc308ac9d1
--- /dev/null
+++ b/dev/benchmarks/complex_layout/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/dev/benchmarks/complex_layout/ohos/oh-package.json5 b/dev/benchmarks/complex_layout/ohos/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..0547594c0d9fe2de363a80af708744809205c3d1
--- /dev/null
+++ b/dev/benchmarks/complex_layout/ohos/oh-package.json5
@@ -0,0 +1,33 @@
+/*
+* 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",
+ "name": "complex_layout",
+ "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"
+ }
+}
diff --git a/dev/benchmarks/macrobenchmarks/ohos/.gitignore b/dev/benchmarks/macrobenchmarks/ohos/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6ca13b3170eec5dd5ac5ad7f1c4dd0118845f473
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/AppScope/app.json5 b/dev/benchmarks/macrobenchmarks/ohos/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..2da1f2376301f72fca68975274e6a17c2d5b10cb
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/AppScope/app.json5
@@ -0,0 +1,10 @@
+{
+ "app": {
+ "bundleName": "com.example.macrobenchmarks",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/dev/benchmarks/macrobenchmarks/ohos/AppScope/resources/base/element/string.json b/dev/benchmarks/macrobenchmarks/ohos/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..eb870aabd077d622d40df3a6fc2caedae864e22a
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "macrobenchmarks"
+ }
+ ]
+}
diff --git a/dev/benchmarks/macrobenchmarks/ohos/AppScope/resources/base/media/app_icon.png b/dev/benchmarks/macrobenchmarks/ohos/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/dev/benchmarks/macrobenchmarks/ohos/AppScope/resources/base/media/app_icon.png differ
diff --git a/dev/benchmarks/macrobenchmarks/ohos/build-profile.json5 b/dev/benchmarks/macrobenchmarks/ohos/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..5fcb3dc466ec0efe97a15ac93a397ddcc0ec6c56
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/build-profile.json5
@@ -0,0 +1,42 @@
+/*
+* 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.
+*/
+
+{
+ "app": {
+ "signingConfigs": [],
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ "compatibleSdkVersion": "4.1.0(11)",
+ "runtimeOS": "HarmonyOS",
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/dev/benchmarks/macrobenchmarks/ohos/dta/icudtl.dat b/dev/benchmarks/macrobenchmarks/ohos/dta/icudtl.dat
new file mode 100644
index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67
Binary files /dev/null and b/dev/benchmarks/macrobenchmarks/ohos/dta/icudtl.dat differ
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/.gitignore b/dev/benchmarks/macrobenchmarks/ohos/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/entry/.gitignore
@@ -0,0 +1,7 @@
+
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/build-profile.json5 b/dev/benchmarks/macrobenchmarks/ohos/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/hvigorfile.ts b/dev/benchmarks/macrobenchmarks/ohos/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/oh-package.json5 b/dev/benchmarks/macrobenchmarks/ohos/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..dabaee13151003854589516fcfb20ccd29c44b6b
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/entry/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": "entry",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {
+ },
+}
+
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8bc48be8773196f34cccb15cf517f87f5c6b94d2
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/ets/pages/Index.ets b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1125f9fdd95f4310a182c1c9e3680f37f73686c9
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f28ced70d552f7990164a9caa7c82413e11534a6
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets
@@ -0,0 +1,24 @@
+import { FlutterEngine, Log } from '@ohos/flutter_ohos';
+
+/**
+ * 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 {
+ } catch (e) {
+ Log.e(
+ TAG,
+ "Tried to register plugins with FlutterEngine ("
+ + flutterEngine
+ + ") failed.");
+ Log.e(TAG, "Received exception while registering", e);
+ }
+ }
+}
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/module.json5 b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/module.json5
@@ -0,0 +1,53 @@
+/*
+* 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"
+ ]
+ }
+ ]
+ }
+ ],
+ "requestPermissions": [
+ {"name" : "ohos.permission.INTERNET"},
+ ]
+ }
+}
\ No newline at end of file
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/element/color.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/element/string.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..9d40485cdb4242c5b91b815ff4a7a976dad9cf9c
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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": "macrobenchmarks"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/media/icon.png b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/media/icon.png differ
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/profile/main_pages.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/en_US/element/string.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/en_US/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..9d40485cdb4242c5b91b815ff4a7a976dad9cf9c
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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": "macrobenchmarks"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/zh_CN/element/string.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..fdb86ef3cd7a7404954005ab0eaab8c103b11226
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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": "macrobenchmarks"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/test/List.test.ets b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/module.json5 b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/element/color.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/element/string.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/media/icon.png b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/media/icon.png differ
diff --git a/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "testability/pages/Index"
+ ]
+}
diff --git a/dev/benchmarks/macrobenchmarks/ohos/hvigor/hvigor-config.json5 b/dev/benchmarks/macrobenchmarks/ohos/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..541ba35711b75986f9295410ee38fdb8f2572878
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/hvigor/hvigor-config.json5
@@ -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.
+*/
+
+{
+ "modelVersion": "5.0.0",
+ "dependencies": {
+ }
+}
\ No newline at end of file
diff --git a/dev/benchmarks/macrobenchmarks/ohos/hvigorfile.ts b/dev/benchmarks/macrobenchmarks/ohos/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8f2d2aafe6d6a3a71a9944ebd0c91fbc308ac9d1
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/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/dev/benchmarks/macrobenchmarks/ohos/oh-package.json5 b/dev/benchmarks/macrobenchmarks/ohos/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c640999ec2753fcc36c68f3ac72342b35278a71d
--- /dev/null
+++ b/dev/benchmarks/macrobenchmarks/ohos/oh-package.json5
@@ -0,0 +1,33 @@
+/*
+* 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",
+ "name": "macrobenchmarks",
+ "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"
+ }
+}
diff --git a/dev/benchmarks/macrobenchmarks/test_driver/large_image_changer_test.dart b/dev/benchmarks/macrobenchmarks/test_driver/large_image_changer_test.dart
index 184c6db9fd4737d97507a4e1ed0c23f01523a6a2..dca971527bd1aedb0409690f8e0f253aedf31d0c 100644
--- a/dev/benchmarks/macrobenchmarks/test_driver/large_image_changer_test.dart
+++ b/dev/benchmarks/macrobenchmarks/test_driver/large_image_changer_test.dart
@@ -23,6 +23,7 @@ Future main() async {
});
}
case 'TargetPlatform.android':
+ case 'TargetPlatform.ohos':
{
// Just run for 20 seconds to collect memory usage. The widget itself
// animates during this time.
diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart
index c6d1a2e22a537f609851d901860f23d51a8c600a..59cf2bce0e4759add4e90cfcdd6929101e18c58b 100644
--- a/dev/devicelab/lib/tasks/perf_tests.dart
+++ b/dev/devicelab/lib/tasks/perf_tests.dart
@@ -1382,6 +1382,8 @@ class PerfTest {
'--use-existing-app',
existingApp
],
+ if (writeSkslFileName != null) ...['--write-sksl-on-exit', writeSkslFileName],
+ if (cacheSkSL) '--cache-sksl',
if (dartDefine.isNotEmpty) ...['--dart-define', dartDefine],
if (enableImpeller != null && enableImpeller!) '--enable-impeller',
if (enableImpeller != null && !enableImpeller!)
@@ -1399,7 +1401,8 @@ class PerfTest {
await resetPlist();
}
- final Map data = json.decode(
+ final Map data = json.decode
+
file('${_testOutputDirectory(testDirectory)}/$resultFilename.json').readAsStringSync(),
) as Map;
diff --git a/dev/integration_tests/flutter_gallery/lib/demo/material/drawer_demo.dart b/dev/integration_tests/flutter_gallery/lib/demo/material/drawer_demo.dart
index bf1291f9b8d92d02da5478c8d6b854b3ef3c696d..82e402eab037b1d5695ca9957f15b289a70429dc 100644
--- a/dev/integration_tests/flutter_gallery/lib/demo/material/drawer_demo.dart
+++ b/dev/integration_tests/flutter_gallery/lib/demo/material/drawer_demo.dart
@@ -65,6 +65,7 @@ class _DrawerDemoState extends State with TickerProviderStateMixin {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
+ case TargetPlatform.ohos:
case TargetPlatform.windows:
return Icons.arrow_back;
case TargetPlatform.iOS:
diff --git a/dev/integration_tests/flutter_gallery/lib/gallery/options.dart b/dev/integration_tests/flutter_gallery/lib/gallery/options.dart
index 12eecbe4986d88b3eb72825ac1d90dab5362b7d8..9d2c76dabe759ab30e42477bf7d89e3d14e97cfd 100644
--- a/dev/integration_tests/flutter_gallery/lib/gallery/options.dart
+++ b/dev/integration_tests/flutter_gallery/lib/gallery/options.dart
@@ -414,6 +414,7 @@ class _PlatformItem extends StatelessWidget {
TargetPlatform.android => 'Mountain View',
TargetPlatform.fuchsia => 'Fuchsia',
TargetPlatform.iOS => 'Cupertino',
+ TargetPlatform.ohos => 'Ohos',
TargetPlatform.linux => 'Material Desktop (linux)',
TargetPlatform.macOS => 'Material Desktop (macOS)',
TargetPlatform.windows => 'Material Desktop (Windows)',
diff --git a/dev/integration_tests/new_gallery/lib/studies/reply/mail_card_preview.dart b/dev/integration_tests/new_gallery/lib/studies/reply/mail_card_preview.dart
index 86058ca5556c8b0a0028db8c5b506e8b5a8d21cd..1ea27c4bf66c1af239b9d8fa9fd9164bf4af3fe8 100644
--- a/dev/integration_tests/new_gallery/lib/studies/reply/mail_card_preview.dart
+++ b/dev/integration_tests/new_gallery/lib/studies/reply/mail_card_preview.dart
@@ -266,6 +266,7 @@ class _PicturePreview extends StatelessWidget {
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
case TargetPlatform.android:
+ case TargetPlatform.ohos:
return true;
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
diff --git a/dev/integration_tests/new_gallery/lib/studies/reply/mail_view_page.dart b/dev/integration_tests/new_gallery/lib/studies/reply/mail_view_page.dart
index 914394e81375c6c1abbc2fda27ec1958c03e0263..476c439391459686e8fb8e4256b2ab2b2ce840f6 100644
--- a/dev/integration_tests/new_gallery/lib/studies/reply/mail_view_page.dart
+++ b/dev/integration_tests/new_gallery/lib/studies/reply/mail_view_page.dart
@@ -144,6 +144,7 @@ class _PictureGrid extends StatelessWidget {
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
case TargetPlatform.android:
+ case TargetPlatform.ohos:
return true;
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
diff --git a/dev/tools/bin/find_commit.dart b/dev/tools/bin/find_commit.dart
index 33289f90f33ed4fdf98016c8c4a6917e74de0689..3f6eedae189a0ba6a6cc5aa516d04a897348e1db 100644
--- a/dev/tools/bin/find_commit.dart
+++ b/dev/tools/bin/find_commit.dart
@@ -10,7 +10,7 @@
import 'dart:io';
-const bool debugLogging = false;
+const bool debugLogging = true;
void log(String message) {
if (debugLogging) {
@@ -49,12 +49,18 @@ String findCommit({
}
}
}
+ final String currentBranch = git(secondaryRepoDirectory, [
+ 'rev-parse',
+ '--abbrev-ref',
+ 'HEAD'
+ ]).trim();
+
return git(secondaryRepoDirectory, [
'log',
'--format=%H',
'--until=${anchor.toIso8601String()}',
'--max-count=1',
- secondaryBranch,
+ currentBranch,
'--',
]);
}
@@ -62,7 +68,7 @@ String findCommit({
String git(String workingDirectory, List arguments, {bool allowFailure = false}) {
final ProcessResult result = Process.runSync('git', arguments, workingDirectory: workingDirectory);
if (!allowFailure && result.exitCode != 0 || '${result.stderr}'.isNotEmpty) {
- throw ProcessException('git', arguments, '${result.stdout}${result.stderr}', result.exitCode);
+ throw ProcessException('git', arguments, 'working directory: "$workingDirectory"\n${result.stdout}\n${result.stderr}', result.exitCode);
}
return '${result.stdout}';
}
diff --git a/dev/tools/bin/generate_gradle_lockfiles.dart b/dev/tools/bin/generate_gradle_lockfiles.dart
index 4695b18813af41ec8515a996f3b5cfbcd8bd93bf..37575a201f7b9c7e646b86204d2d6e49b6aef580 100644
--- a/dev/tools/bin/generate_gradle_lockfiles.dart
+++ b/dev/tools/bin/generate_gradle_lockfiles.dart
@@ -174,6 +174,24 @@ const String rootGradleFileContent = r'''
// To update all the build.gradle files in the Flutter repo,
// See dev/tools/bin/generate_gradle_lockfiles.dart.
+buildscript {
+ ext.kotlin_version = '1.7.10'
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.3.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+
+ configurations.classpath {
+ resolutionStrategy.activateDependencyLocking()
+ }
+}
+
+>>>>>>> dev
allprojects {
repositories {
google()
diff --git a/examples/api/lib/material/context_menu/context_menu_controller.0.dart b/examples/api/lib/material/context_menu/context_menu_controller.0.dart
index 99e77ec9353d25cc9373852687dfb03f5c0fc222..100b0a54f07c78bfcd43a59b5a4e70c3010cf41a 100644
--- a/examples/api/lib/material/context_menu/context_menu_controller.0.dart
+++ b/examples/api/lib/material/context_menu/context_menu_controller.0.dart
@@ -120,6 +120,7 @@ class _ContextMenuRegionState extends State<_ContextMenuRegion> {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.iOS:
+ case TargetPlatform.ohos:
return true;
case TargetPlatform.macOS:
case TargetPlatform.fuchsia:
diff --git a/examples/api/lib/material/dialog/adaptive_alert_dialog.0.dart b/examples/api/lib/material/dialog/adaptive_alert_dialog.0.dart
index 08b760cfb313d5d27b5ebd67eaae555fda43a2a2..9cb3f05ddb862170eaf8083658b11c8f96de8422 100644
--- a/examples/api/lib/material/dialog/adaptive_alert_dialog.0.dart
+++ b/examples/api/lib/material/dialog/adaptive_alert_dialog.0.dart
@@ -41,6 +41,7 @@ class AdaptiveDialogExample extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return TextButton(onPressed: onPressed, child: child);
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/examples/api/lib/material/menu_anchor/menu_anchor.1.dart b/examples/api/lib/material/menu_anchor/menu_anchor.1.dart
index e6b6d07f2e47673f84fcf86f574dcc42328242c4..5a2c37a7a8606a0f8600fbd9ce24f8296aca33b1 100644
--- a/examples/api/lib/material/menu_anchor/menu_anchor.1.dart
+++ b/examples/api/lib/material/menu_anchor/menu_anchor.1.dart
@@ -229,6 +229,7 @@ class _MyContextMenuState extends State {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
// Don't open the menu on these platforms with a Ctrl-tap (or a
// tap).
break;
diff --git a/examples/api/lib/material/switch/switch.4.dart b/examples/api/lib/material/switch/switch.4.dart
index 4d64608f86fe3a0e864fc9f500eef049abed9756..6084b77b31519fbe56fece1f86b4130034a2bdcd 100644
--- a/examples/api/lib/material/switch/switch.4.dart
+++ b/examples/api/lib/material/switch/switch.4.dart
@@ -117,6 +117,7 @@ class _SwitchThemeAdaptation extends Adaptation {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return defaultValue;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/examples/api/lib/widgets/draggable_scrollable_sheet/draggable_scrollable_sheet.0.dart b/examples/api/lib/widgets/draggable_scrollable_sheet/draggable_scrollable_sheet.0.dart
index f904102678b41d14fef629fb9f075cdb83774e7d..87f9a106352ebf53bffe0286ab75c5a5d458a14a 100644
--- a/examples/api/lib/widgets/draggable_scrollable_sheet/draggable_scrollable_sheet.0.dart
+++ b/examples/api/lib/widgets/draggable_scrollable_sheet/draggable_scrollable_sheet.0.dart
@@ -97,6 +97,7 @@ class _DraggableScrollableSheetExampleState extends State with TickerProviderSt
case TargetPlatform.android:
case TargetPlatform.iOS:
case TargetPlatform.fuchsia:
+ case TargetPlatform.ohos:
return false;
}
}
diff --git a/examples/api/test/material/context_menu/editable_text_toolbar_builder.2_test.dart b/examples/api/test/material/context_menu/editable_text_toolbar_builder.2_test.dart
index 2bcf2ea61d78a61d85d0edb160845116f53fd813..88539c89d1c79d4cdd0424c9741ab4105d196b28 100644
--- a/examples/api/test/material/context_menu/editable_text_toolbar_builder.2_test.dart
+++ b/examples/api/test/material/context_menu/editable_text_toolbar_builder.2_test.dart
@@ -34,6 +34,7 @@ void main() {
expect(find.byType(CupertinoTextSelectionToolbarButton), findsAtLeastNWidgets(1));
case TargetPlatform.android:
case TargetPlatform.fuchsia:
+ case TargetPlatform.ohos:
expect(find.byType(TextSelectionToolbarTextButton), findsAtLeastNWidgets(1));
case TargetPlatform.linux:
case TargetPlatform.windows:
diff --git a/examples/platform_view/lib/main.dart b/examples/platform_view/lib/main.dart
index 5efefe72ffd4a3cd4be9aa2d0b73d92d28293f7c..e81b4243d15c658c2c6ddc6dd8982769f4aa5adc 100644
--- a/examples/platform_view/lib/main.dart
+++ b/examples/platform_view/lib/main.dart
@@ -51,6 +51,7 @@ class _MyHomePageState extends State {
return switch (defaultTargetPlatform) {
TargetPlatform.android => const Text('Continue in Android view'),
TargetPlatform.iOS => const Text('Continue in iOS view'),
+ TargetPlatform.ohos => const Text('Continue in Ohos view'),
TargetPlatform.windows => const Text('Continue in Windows view'),
TargetPlatform.macOS => const Text('Continue in macOS view'),
TargetPlatform.linux => const Text('Continue in Linux view'),
diff --git a/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart b/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart
index 0f88c306d33913b1e695bd9a8b4addd6087822b2..1fc2d7a161313ed2c4d41ce84d67cf9633ec19b9 100644
--- a/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart
+++ b/packages/flutter/lib/src/cupertino/adaptive_text_selection_toolbar.dart
@@ -188,6 +188,7 @@ class CupertinoAdaptiveTextSelectionToolbar extends StatelessWidget {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
+ case TargetPlatform.ohos:
return buttonItems.map((ContextMenuButtonItem buttonItem) {
return CupertinoTextSelectionToolbarButton.buttonItem(
buttonItem: buttonItem,
@@ -218,6 +219,7 @@ class CupertinoAdaptiveTextSelectionToolbar extends StatelessWidget {
case TargetPlatform.android:
case TargetPlatform.iOS:
case TargetPlatform.fuchsia:
+ case TargetPlatform.ohos:
return CupertinoTextSelectionToolbar(
anchorAbove: anchors.primaryAnchor,
anchorBelow: anchors.secondaryAnchor ?? anchors.primaryAnchor,
diff --git a/packages/flutter/lib/src/cupertino/app.dart b/packages/flutter/lib/src/cupertino/app.dart
index b82216954c1d3c779d3d3db61ee4c652fa76c304..d5988efd145ebbccc7f76a37f5733eee062031e8 100644
--- a/packages/flutter/lib/src/cupertino/app.dart
+++ b/packages/flutter/lib/src/cupertino/app.dart
@@ -469,6 +469,7 @@ class CupertinoScrollBehavior extends ScrollBehavior {
controller: details.controller,
child: child,
);
+ case TargetPlatform.ohos:
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
diff --git a/packages/flutter/lib/src/cupertino/picker.dart b/packages/flutter/lib/src/cupertino/picker.dart
index 88a70f1cc842bf31c7ee1af9c3c116c52adf5bf4..05f390c55392ce0320e55a92a68f12d3839724e9 100644
--- a/packages/flutter/lib/src/cupertino/picker.dart
+++ b/packages/flutter/lib/src/cupertino/picker.dart
@@ -243,6 +243,7 @@ class _CupertinoPickerState extends State {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.macOS:
+ case TargetPlatform.ohos:
case TargetPlatform.windows:
hasSuitableHapticHardware = false;
}
diff --git a/packages/flutter/lib/src/cupertino/radio.dart b/packages/flutter/lib/src/cupertino/radio.dart
index 52b752c847126c287d89171152c8f9c2082b18bc..48bcfa16ba91fdeb1ed0c5cb489104824bf31285 100644
--- a/packages/flutter/lib/src/cupertino/radio.dart
+++ b/packages/flutter/lib/src/cupertino/radio.dart
@@ -248,6 +248,7 @@ class _CupertinoRadioState extends State> with TickerProvid
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
accessibilitySelected = null;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/cupertino/switch.dart b/packages/flutter/lib/src/cupertino/switch.dart
index b864fd5e98cee267cab4b9f1c6d1b71290901922..668c04ae5604f275a01142cad38a8e588c3c449b 100644
--- a/packages/flutter/lib/src/cupertino/switch.dart
+++ b/packages/flutter/lib/src/cupertino/switch.dart
@@ -348,6 +348,7 @@ class _CupertinoSwitchState extends State with TickerProviderSt
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
break;
}
}
diff --git a/packages/flutter/lib/src/cupertino/text_field.dart b/packages/flutter/lib/src/cupertino/text_field.dart
index 9948bd96d98a1dd14cffe369c5da6200eab03aab..af97efd97977f6e1646a5d93cd5b005a5f272668 100644
--- a/packages/flutter/lib/src/cupertino/text_field.dart
+++ b/packages/flutter/lib/src/cupertino/text_field.dart
@@ -887,6 +887,7 @@ class CupertinoTextField extends StatefulWidget {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.iOS:
+ case TargetPlatform.ohos:
return CupertinoTextMagnifier(
controller: controller,
magnifierInfo: magnifierInfo,
@@ -1068,7 +1069,9 @@ class _CupertinoTextFieldState extends State with Restoratio
case TargetPlatform.windows:
case TargetPlatform.fuchsia:
case TargetPlatform.android:
- if (cause == SelectionChangedCause.longPress) {
+ case TargetPlatform.ohos:
+ if (cause == SelectionChangedCause.longPress
+ || cause == SelectionChangedCause.drag) {
_editableText.bringIntoView(selection.extent);
}
}
@@ -1077,6 +1080,7 @@ class _CupertinoTextFieldState extends State with Restoratio
case TargetPlatform.iOS:
case TargetPlatform.fuchsia:
case TargetPlatform.android:
+ case TargetPlatform.ohos:
break;
case TargetPlatform.macOS:
case TargetPlatform.linux:
@@ -1266,6 +1270,7 @@ class _CupertinoTextFieldState extends State with Restoratio
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
+ case TargetPlatform.ohos:
textSelectionControls ??= cupertinoTextSelectionHandleControls;
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/foundation/_platform_io.dart b/packages/flutter/lib/src/foundation/_platform_io.dart
index 7fd4f35ff7ac8daec4233d00f74d04a51300c47e..e6fd464314341dece45d25b582fd269af9c79ca2 100644
--- a/packages/flutter/lib/src/foundation/_platform_io.dart
+++ b/packages/flutter/lib/src/foundation/_platform_io.dart
@@ -25,6 +25,8 @@ platform.TargetPlatform get defaultTargetPlatform {
result = platform.TargetPlatform.macOS;
} else if (Platform.isWindows) {
result = platform.TargetPlatform.windows;
+ } else if (Platform.operatingSystem == 'ohos') {
+ result = platform.TargetPlatform.ohos;
}
assert(() {
if (Platform.environment.containsKey('FLUTTER_TEST')) {
diff --git a/packages/flutter/lib/src/foundation/_platform_web.dart b/packages/flutter/lib/src/foundation/_platform_web.dart
index 161921fba4313a7e0a2f1cbfc4b4b929a26199a3..ca40ccb5c20c9d0f7ec8d598bf63bca63b6b1500 100644
--- a/packages/flutter/lib/src/foundation/_platform_web.dart
+++ b/packages/flutter/lib/src/foundation/_platform_web.dart
@@ -52,6 +52,9 @@ final platform.TargetPlatform _browserPlatform = () {
if (navigatorPlatform.contains('android')) {
return platform.TargetPlatform.android;
}
+ if (navigatorPlatform.contains('ohos')) {
+ return platform.TargetPlatform.ohos;
+ }
// Since some phones can report a window.navigator.platform as Linux, fall
// back to use CSS to disambiguate Android vs Linux desktop. If the CSS
// indicates that a device has a "fine pointer" (mouse) as the primary
diff --git a/packages/flutter/lib/src/foundation/platform.dart b/packages/flutter/lib/src/foundation/platform.dart
index b1905aea1a95c10d56cf59e1529a77f4f367a339..64bec6567247bb6501420d8d660e8a56fb8c24d2 100644
--- a/packages/flutter/lib/src/foundation/platform.dart
+++ b/packages/flutter/lib/src/foundation/platform.dart
@@ -77,6 +77,9 @@ enum TargetPlatform {
/// Windows:
windows,
+
+ /// Ohos
+ ohos,
}
/// Override the [defaultTargetPlatform] in debug builds.
diff --git a/packages/flutter/lib/src/material/action_buttons.dart b/packages/flutter/lib/src/material/action_buttons.dart
index c417bfb2e19fcbc07d4d1d81b69d827fc1da369d..ed842ecee1c12328ca189065f518a6f07c07f082 100644
--- a/packages/flutter/lib/src/material/action_buttons.dart
+++ b/packages/flutter/lib/src/material/action_buttons.dart
@@ -110,6 +110,7 @@ class _ActionIcon extends StatelessWidget {
case TargetPlatform.windows:
case TargetPlatform.iOS:
case TargetPlatform.macOS:
+ case TargetPlatform.ohos:
semanticsLabel = null;
}
@@ -150,6 +151,7 @@ class BackButtonIcon extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return Icons.arrow_back;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart b/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart
index cb5c29d1fddbe78135061b80d9c188fad2299f80..89f0cde9f685f436d7fc12b54722884a567912a9 100644
--- a/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart
+++ b/packages/flutter/lib/src/material/adaptive_text_selection_toolbar.dart
@@ -209,6 +209,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
+ case TargetPlatform.ohos:
case TargetPlatform.windows:
assert(debugCheckHasMaterialLocalizations(context));
final MaterialLocalizations localizations = MaterialLocalizations.of(context);
@@ -256,6 +257,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget {
});
case TargetPlatform.fuchsia:
case TargetPlatform.android:
+ case TargetPlatform.ohos:
final List buttons = [];
for (int i = 0; i < buttonItems.length; i++) {
final ContextMenuButtonItem buttonItem = buttonItems[i];
@@ -305,6 +307,7 @@ class AdaptiveTextSelectionToolbar extends StatelessWidget {
anchorBelow: anchors.secondaryAnchor == null ? anchors.primaryAnchor : anchors.secondaryAnchor!,
children: resultChildren,
);
+ case TargetPlatform.ohos:
case TargetPlatform.android:
return TextSelectionToolbar(
anchorAbove: anchors.primaryAnchor,
diff --git a/packages/flutter/lib/src/material/app.dart b/packages/flutter/lib/src/material/app.dart
index 6560e015e3ddd376ab07ca42b903a980ac511d77..f77e0eda0002a44940b33b5b7e1ed5271786f235 100644
--- a/packages/flutter/lib/src/material/app.dart
+++ b/packages/flutter/lib/src/material/app.dart
@@ -852,6 +852,7 @@ class MaterialScrollBehavior extends ScrollBehavior {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
+ case TargetPlatform.ohos:
return child;
}
}
@@ -871,6 +872,7 @@ class MaterialScrollBehavior extends ScrollBehavior {
case TargetPlatform.windows:
return child;
case TargetPlatform.android:
+ case TargetPlatform.ohos:
switch (indicator) {
case AndroidOverscrollIndicator.stretch:
return StretchingOverscrollIndicator(
diff --git a/packages/flutter/lib/src/material/app_bar.dart b/packages/flutter/lib/src/material/app_bar.dart
index dee365886c73bd848c8f31cc5e4aac7806e0257b..a80c36e670c6ee9f36e63b4ecd005f9840ab941e 100644
--- a/packages/flutter/lib/src/material/app_bar.dart
+++ b/packages/flutter/lib/src/material/app_bar.dart
@@ -734,9 +734,11 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
bool platformCenter() {
switch (theme.platform) {
case TargetPlatform.android:
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return false;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -973,7 +975,7 @@ class _AppBarState extends State {
if (!widget.excludeHeaderSemantics) {
title = Semantics(
namesRoute: switch (theme.platform) {
- TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.linux || TargetPlatform.windows => true,
+ TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.linux || TargetPlatform.windows || TargetPlatform.ohos => true,
TargetPlatform.iOS || TargetPlatform.macOS => null,
},
header: true,
diff --git a/packages/flutter/lib/src/material/bottom_sheet.dart b/packages/flutter/lib/src/material/bottom_sheet.dart
index e9a986aeba9d63f9333ac554566a743d5b59722d..cd58af5f7af55a56ab00a957793e3668002971f3 100644
--- a/packages/flutter/lib/src/material/bottom_sheet.dart
+++ b/packages/flutter/lib/src/material/bottom_sheet.dart
@@ -690,6 +690,7 @@ class _ModalBottomSheetState extends State<_ModalBottomSheet> {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return localizations.dialogLabel;
}
}
diff --git a/packages/flutter/lib/src/material/calendar_date_picker.dart b/packages/flutter/lib/src/material/calendar_date_picker.dart
index aa25b7e1f86dac6884a12cc63a37f4324cfc1022..c5920c494f7ebc04846668f8da03030054be7389 100644
--- a/packages/flutter/lib/src/material/calendar_date_picker.dart
+++ b/packages/flutter/lib/src/material/calendar_date_picker.dart
@@ -200,6 +200,7 @@ class _CalendarDatePickerState extends State {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
HapticFeedback.vibrate();
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -277,6 +278,7 @@ class _CalendarDatePickerState extends State {
);
case TargetPlatform.android:
case TargetPlatform.iOS:
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
break;
}
diff --git a/packages/flutter/lib/src/material/checkbox.dart b/packages/flutter/lib/src/material/checkbox.dart
index 5d289aca6d5a1ccfe8ddd09a2ff6a3cbfd112d10..b16eb63946d53fbc2058d12a262890751ec71b94 100644
--- a/packages/flutter/lib/src/material/checkbox.dart
+++ b/packages/flutter/lib/src/material/checkbox.dart
@@ -479,6 +479,7 @@ class _CheckboxState extends State with TickerProviderStateMixin, Togg
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/material/date_picker.dart b/packages/flutter/lib/src/material/date_picker.dart
index f4f832f6f6ab4ba1c1299c5ade0b7a04205d4896..8912bb97327a474daa0809f73a509292a8d18ebc 100644
--- a/packages/flutter/lib/src/material/date_picker.dart
+++ b/packages/flutter/lib/src/material/date_picker.dart
@@ -1857,6 +1857,7 @@ class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
break;
}
}
diff --git a/packages/flutter/lib/src/material/dialog.dart b/packages/flutter/lib/src/material/dialog.dart
index 1659dad97a0ba028eb0f89415c37f5712615903f..730ec409fec46049315c323e15f930ae13a2c3a1 100644
--- a/packages/flutter/lib/src/material/dialog.dart
+++ b/packages/flutter/lib/src/material/dialog.dart
@@ -720,6 +720,7 @@ class AlertDialog extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
label ??= MaterialLocalizations.of(context).alertDialogLabel;
}
@@ -943,6 +944,7 @@ class _AdaptiveAlertDialog extends AlertDialog {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -1217,6 +1219,7 @@ class SimpleDialog extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
label ??= MaterialLocalizations.of(context).dialogLabel;
}
@@ -1473,6 +1476,7 @@ Future showAdaptiveDialog({
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return showDialog(
context: context,
builder: builder,
diff --git a/packages/flutter/lib/src/material/drawer.dart b/packages/flutter/lib/src/material/drawer.dart
index e27eb149a6b916423d00cbe06f37848196b5b624..3567f43e1bfd2c9e9bf7e325fdc583968ed4bb57 100644
--- a/packages/flutter/lib/src/material/drawer.dart
+++ b/packages/flutter/lib/src/material/drawer.dart
@@ -246,6 +246,7 @@ class Drawer extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
label = semanticLabel ?? MaterialLocalizations.of(context).drawerLabel;
}
final bool useMaterial3 = Theme.of(context).useMaterial3;
@@ -659,7 +660,7 @@ class DrawerControllerState extends State with SingleTickerPro
Widget _buildDrawer(BuildContext context) {
final bool isDesktop = switch (Theme.of(context).platform) {
- TargetPlatform.android || TargetPlatform.iOS || TargetPlatform.fuchsia => false,
+ TargetPlatform.android || TargetPlatform.iOS || TargetPlatform.fuchsia || TargetPlatform.ohos => false,
TargetPlatform.macOS || TargetPlatform.linux || TargetPlatform.windows => true,
};
@@ -693,6 +694,8 @@ class DrawerControllerState extends State with SingleTickerPro
switch (Theme.of(context).platform) {
case TargetPlatform.android:
platformHasBackButton = true;
+ break;
+ case TargetPlatform.ohos:
case TargetPlatform.iOS:
case TargetPlatform.macOS:
case TargetPlatform.fuchsia:
diff --git a/packages/flutter/lib/src/material/dropdown_menu.dart b/packages/flutter/lib/src/material/dropdown_menu.dart
index 6ac09b52ee40db93e40e925c65f0350686474386..4672e079bc0ce29ad38f7320813740154d0757ba 100644
--- a/packages/flutter/lib/src/material/dropdown_menu.dart
+++ b/packages/flutter/lib/src/material/dropdown_menu.dart
@@ -486,7 +486,7 @@ class _DropdownMenuState extends State> {
bool canRequestFocus() {
return widget.focusNode?.canRequestFocus ?? widget.requestFocusOnTap
?? switch (Theme.of(context).platform) {
- TargetPlatform.iOS || TargetPlatform.android || TargetPlatform.fuchsia => false,
+ TargetPlatform.iOS || TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.ohos => false,
TargetPlatform.macOS || TargetPlatform.linux || TargetPlatform.windows => true,
};
}
diff --git a/packages/flutter/lib/src/material/expansion_tile.dart b/packages/flutter/lib/src/material/expansion_tile.dart
index 0c736c6639d68deddf3e0aafe90d3188997f1249..1bbb86e919cb40339b1b42069b833067c76124bb 100644
--- a/packages/flutter/lib/src/material/expansion_tile.dart
+++ b/packages/flutter/lib/src/material/expansion_tile.dart
@@ -702,6 +702,7 @@ class _ExpansionTileState extends State with SingleTickerProvider
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
break;
}
diff --git a/packages/flutter/lib/src/material/feedback.dart b/packages/flutter/lib/src/material/feedback.dart
index cfb3a063480bf8029c5a7e1d605f4a9edf2d156f..cad8df3d64525b95da803ad3b36ef337d2401a4e 100644
--- a/packages/flutter/lib/src/material/feedback.dart
+++ b/packages/flutter/lib/src/material/feedback.dart
@@ -100,6 +100,7 @@ abstract final class Feedback {
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return Future.value();
}
}
@@ -143,6 +144,7 @@ abstract final class Feedback {
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return Future.value();
}
}
diff --git a/packages/flutter/lib/src/material/flexible_space_bar.dart b/packages/flutter/lib/src/material/flexible_space_bar.dart
index 34e24a72ee81e718a4e6b9a83d92b86f01f99e25..46bf0d79e1247c06af98f0cec97480d4a22bd806 100644
--- a/packages/flutter/lib/src/material/flexible_space_bar.dart
+++ b/packages/flutter/lib/src/material/flexible_space_bar.dart
@@ -186,7 +186,7 @@ class FlexibleSpaceBar extends StatefulWidget {
class _FlexibleSpaceBarState extends State {
bool _getEffectiveCenterTitle(ThemeData theme) {
return widget.centerTitle ?? switch (theme.platform) {
- TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.linux || TargetPlatform.windows => false,
+ TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.linux || TargetPlatform.windows || TargetPlatform.ohos => false,
TargetPlatform.iOS || TargetPlatform.macOS => true,
};
}
@@ -290,6 +290,7 @@ class _FlexibleSpaceBarState extends State {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
title = Semantics(
namesRoute: true,
child: widget.title,
diff --git a/packages/flutter/lib/src/material/icons.dart b/packages/flutter/lib/src/material/icons.dart
index cdf5798213598a485ba870e5bdb648798af191c6..65b2920f4ea6c65c89e967f70a0636c394cca853 100644
--- a/packages/flutter/lib/src/material/icons.dart
+++ b/packages/flutter/lib/src/material/icons.dart
@@ -19,6 +19,7 @@ final class PlatformAdaptiveIcons implements Icons {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return false;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/material/magnifier.dart b/packages/flutter/lib/src/material/magnifier.dart
index 6206d0e16b908d7cc86cceeea41b73d39a083d06..0a4f360beeced17bf4fe55d2f9b7299500df580a 100644
--- a/packages/flutter/lib/src/material/magnifier.dart
+++ b/packages/flutter/lib/src/material/magnifier.dart
@@ -54,6 +54,7 @@ class TextMagnifier extends StatefulWidget {
magnifierInfo: magnifierInfo,
);
case TargetPlatform.android:
+ case TargetPlatform.ohos:
return TextMagnifier(
magnifierInfo: magnifierInfo,
);
diff --git a/packages/flutter/lib/src/material/menu_anchor.dart b/packages/flutter/lib/src/material/menu_anchor.dart
index adf61adbf47a83dbf8710222f3dd93e3ab1448f1..9ad6b046889c2c830eeeecc085ccc9400097f701 100644
--- a/packages/flutter/lib/src/material/menu_anchor.dart
+++ b/packages/flutter/lib/src/material/menu_anchor.dart
@@ -2213,6 +2213,7 @@ class _LocalizedShortcutLabeler {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
+ case TargetPlatform.ohos:
case TargetPlatform.linux:
return localizations.keyboardKeyMeta;
case TargetPlatform.windows:
@@ -2230,6 +2231,7 @@ class _LocalizedShortcutLabeler {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return localizations.keyboardKeyAlt;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -2249,6 +2251,7 @@ class _LocalizedShortcutLabeler {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return localizations.keyboardKeyControl;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -2263,6 +2266,7 @@ class _LocalizedShortcutLabeler {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return localizations.keyboardKeyShift;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -3568,6 +3572,7 @@ bool get _isApple {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return false;
}
}
diff --git a/packages/flutter/lib/src/material/page_transitions_theme.dart b/packages/flutter/lib/src/material/page_transitions_theme.dart
index cbcfa2cf2647c0a27c22e46eb2644419c98953aa..3aab43477ab708a61f8eac41ca9a78664f0fe6c7 100644
--- a/packages/flutter/lib/src/material/page_transitions_theme.dart
+++ b/packages/flutter/lib/src/material/page_transitions_theme.dart
@@ -147,6 +147,82 @@ class _OpenUpwardsPageTransition extends StatelessWidget {
}
}
+
+// This transition is intended to match the default for Openharmony.
+class _OpenRightwardsPageTransition extends StatelessWidget {
+ const _OpenRightwardsPageTransition({
+ required this.animation,
+ required this.secondaryAnimation,
+ required this.child,
+ });
+
+ // The new page slides upwards just a little as its clip
+ // rectangle exposes the page from right to left.
+ static final Tween _primaryTranslationTween = Tween(
+ begin: const Offset(1.0, 0),
+ end: Offset.zero,
+ );
+
+ // The old page slides upwards a little as the new page appears.
+ static final Tween _secondaryTranslationTween = Tween(
+ begin: Offset.zero,
+ end: const Offset(-0.2, 0),
+ );
+
+ // Used by all of the transition animations.
+ static const Curve _transitionCurve = Cubic(0.20, 0.00, 0.00, 1.00);
+
+ final Animation animation;
+ final Animation secondaryAnimation;
+ final Widget child;
+
+ @override
+ Widget build(BuildContext context) {
+ return LayoutBuilder(
+ builder: (BuildContext context, BoxConstraints constraints) {
+ final Size size = constraints.biggest;
+
+ final CurvedAnimation primaryAnimation = CurvedAnimation(
+ parent: animation,
+ curve: _transitionCurve,
+ reverseCurve: _transitionCurve.flipped,
+ );
+
+
+ final Animation primaryTranslationAnimation = _primaryTranslationTween.animate(primaryAnimation);
+
+ final Animation secondaryTranslationAnimation = _secondaryTranslationTween.animate(
+ CurvedAnimation(
+ parent: secondaryAnimation,
+ curve: _transitionCurve,
+ reverseCurve: _transitionCurve.flipped,
+ ),
+ );
+
+ return AnimatedBuilder(
+ animation: animation,
+ builder: (BuildContext context, Widget? child) {
+ return child ?? Container();
+ },
+ child: AnimatedBuilder(
+ animation: secondaryAnimation,
+ child: FractionalTranslation(
+ translation: primaryTranslationAnimation.value,
+ child: child,
+ ),
+ builder: (BuildContext context, Widget? child) {
+ return FractionalTranslation(
+ translation: secondaryTranslationAnimation.value,
+ child: child,
+ );
+ },
+ ),
+ );
+ },
+ );
+ }
+}
+
// Zooms and fades a new page in, zooming out the previous page. This transition
// is designed to match the Android Q activity transition.
class _ZoomPageTransition extends StatelessWidget {
@@ -600,6 +676,27 @@ class OpenUpwardsPageTransitionsBuilder extends PageTransitionsBuilder {
}
}
+class OpenRightwardsPageTransitionsBuilder extends PageTransitionsBuilder {
+ /// Constructs a page transition animation that matches the transition used on
+ /// Openharmony.
+ const OpenRightwardsPageTransitionsBuilder();
+
+ @override
+ Widget buildTransitions(
+ PageRoute? route,
+ BuildContext? context,
+ Animation animation,
+ Animation secondaryAnimation,
+ Widget child,
+ ) {
+ return _OpenRightwardsPageTransition(
+ animation: animation,
+ secondaryAnimation: secondaryAnimation,
+ child: child,
+ );
+ }
+}
+
/// Used by [PageTransitionsTheme] to define a zooming [MaterialPageRoute] page
/// transition animation that looks like the default page transition used on
/// Android Q.
@@ -757,6 +854,7 @@ class PageTransitionsTheme with Diagnosticable {
static const Map _defaultBuilders = {
TargetPlatform.android: ZoomPageTransitionsBuilder(),
+ TargetPlatform.ohos: OpenRightwardsPageTransitionsBuilder(),
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
TargetPlatform.macOS: CupertinoPageTransitionsBuilder(),
};
@@ -860,7 +958,7 @@ class _PageTransitionsThemeTransitionsState extends State<_PageTransitionsThe
final PageTransitionsBuilder matchingBuilder = widget.builders[platform] ?? switch (platform) {
TargetPlatform.iOS => const CupertinoPageTransitionsBuilder(),
- TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.windows || TargetPlatform.macOS || TargetPlatform.linux => const ZoomPageTransitionsBuilder(),
+ TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.windows || TargetPlatform.macOS || TargetPlatform.linux || TargetPlatform.ohos => const ZoomPageTransitionsBuilder(),
};
return matchingBuilder.buildTransitions(
widget.route,
diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart
index fa73e2e233a10c6ed3a6b854614a6074b4aff3d8..cc7004f543743df0352e09712898aa309e634b3a 100644
--- a/packages/flutter/lib/src/material/popup_menu.dart
+++ b/packages/flutter/lib/src/material/popup_menu.dart
@@ -996,6 +996,7 @@ Future showMenu({
case TargetPlatform.macOS:
break;
case TargetPlatform.android:
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
diff --git a/packages/flutter/lib/src/material/progress_indicator.dart b/packages/flutter/lib/src/material/progress_indicator.dart
index 8b4cf3f72486d7c01cccc9d254bd01d7fc6b4f62..087d132ae07d6d675d66180e3a7aae6e0ec0e65f 100644
--- a/packages/flutter/lib/src/material/progress_indicator.dart
+++ b/packages/flutter/lib/src/material/progress_indicator.dart
@@ -777,6 +777,7 @@ class _CircularProgressIndicatorState extends State w
case TargetPlatform.macOS:
return _buildCupertinoIndicator(context);
case TargetPlatform.android:
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
diff --git a/packages/flutter/lib/src/material/radio.dart b/packages/flutter/lib/src/material/radio.dart
index f15260c2e7a603c3f5e9d00b9c75f3f8440f210b..5968da0197c04498f396656a31a834c52748e206 100644
--- a/packages/flutter/lib/src/material/radio.dart
+++ b/packages/flutter/lib/src/material/radio.dart
@@ -438,6 +438,7 @@ class _RadioState extends State> with TickerProviderStateMixin, Togg
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -528,6 +529,7 @@ class _RadioState extends State> with TickerProviderStateMixin, Togg
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
accessibilitySelected = null;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/material/range_slider.dart b/packages/flutter/lib/src/material/range_slider.dart
index 31ca2db167269d0af04bad30ef8410f9b6d0de47..77a1b27c3fdccb3e5dbc33194d5a68dd0eff8aad 100644
--- a/packages/flutter/lib/src/material/range_slider.dart
+++ b/packages/flutter/lib/src/material/range_slider.dart
@@ -1116,6 +1116,7 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
// Matches Android implementation of material slider.
return 0.05;
}
diff --git a/packages/flutter/lib/src/material/refresh_indicator.dart b/packages/flutter/lib/src/material/refresh_indicator.dart
index 12cc5f4b6dd28c6d5b9fa3cb82aa2d645b62a134..ce256f1b9a737dbce0ab7b206b677535599109e3 100644
--- a/packages/flutter/lib/src/material/refresh_indicator.dart
+++ b/packages/flutter/lib/src/material/refresh_indicator.dart
@@ -608,6 +608,7 @@ class RefreshIndicatorState extends State with TickerProviderS
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return materialIndicator;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/material/reorderable_list.dart b/packages/flutter/lib/src/material/reorderable_list.dart
index 2d5c95c11c2aba9473ca37245f29e8c504aea6e4..f7309d673cf178b87e8fad9a4e11c0543dd872e7 100644
--- a/packages/flutter/lib/src/material/reorderable_list.dart
+++ b/packages/flutter/lib/src/material/reorderable_list.dart
@@ -356,6 +356,7 @@ class _ReorderableListViewState extends State {
case TargetPlatform.iOS:
case TargetPlatform.android:
case TargetPlatform.fuchsia:
+ case TargetPlatform.ohos:
return ReorderableDelayedDragStartListener(
key: itemGlobalKey,
index: index,
diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart
index 59e97126aef367e0741599e91dd26827ebeb1616..bd42244943852a106b44f3bdde806e53bf9f708f 100644
--- a/packages/flutter/lib/src/material/scaffold.dart
+++ b/packages/flutter/lib/src/material/scaffold.dart
@@ -3042,6 +3042,7 @@ class ScaffoldState extends State with TickerProviderStateMixin, Resto
removeBottomPadding: true,
);
case TargetPlatform.android:
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
diff --git a/packages/flutter/lib/src/material/scrollbar.dart b/packages/flutter/lib/src/material/scrollbar.dart
index 5f7393fb8915a9e52dd5b2ce057d10c03557b8c8..d94af932691d8e977467669775c6faa7347faee1 100644
--- a/packages/flutter/lib/src/material/scrollbar.dart
+++ b/packages/flutter/lib/src/material/scrollbar.dart
@@ -328,6 +328,7 @@ class _MaterialScrollbarState extends RawScrollbarState<_MaterialScrollbar> {
switch (theme.platform) {
case TargetPlatform.android:
_useAndroidScrollbar = true;
+ case TargetPlatform.ohos:
case TargetPlatform.iOS:
case TargetPlatform.linux:
case TargetPlatform.fuchsia:
diff --git a/packages/flutter/lib/src/material/search.dart b/packages/flutter/lib/src/material/search.dart
index bca887c6e804fd07cd3be2c9d23ccfecb4c2926b..e191b9bb0b00132f3ce03374176c4648e0235137 100644
--- a/packages/flutter/lib/src/material/search.dart
+++ b/packages/flutter/lib/src/material/search.dart
@@ -586,6 +586,7 @@ class _SearchPageState extends State<_SearchPage> {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
routeName = searchFieldLabel;
}
diff --git a/packages/flutter/lib/src/material/search_anchor.dart b/packages/flutter/lib/src/material/search_anchor.dart
index cf7d6c07f16dad3c4d01ecb34fe7d739c2b489e7..237670725be81b8f1e5f3b0b81067c79cd480e00 100644
--- a/packages/flutter/lib/src/material/search_anchor.dart
+++ b/packages/flutter/lib/src/material/search_anchor.dart
@@ -443,7 +443,7 @@ class _SearchAnchorState extends State {
bool getShowFullScreenView() {
return widget.isFullScreen ?? switch (Theme.of(context).platform) {
- TargetPlatform.iOS || TargetPlatform.android || TargetPlatform.fuchsia => true,
+ TargetPlatform.iOS || TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.ohos => true,
TargetPlatform.macOS || TargetPlatform.linux || TargetPlatform.windows => false,
};
}
diff --git a/packages/flutter/lib/src/material/selectable_text.dart b/packages/flutter/lib/src/material/selectable_text.dart
index 90a4ad7f414686f1d14d2998328ebae4c855887c..7821636966e893706484077e487dd68fcb3941da 100644
--- a/packages/flutter/lib/src/material/selectable_text.dart
+++ b/packages/flutter/lib/src/material/selectable_text.dart
@@ -142,6 +142,7 @@ class _SelectableTextSelectionGestureDetectorBuilder extends TextSelectionGestur
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
}
}
@@ -638,6 +639,7 @@ class _SelectableTextState extends State implements TextSelectio
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
// Do nothing.
}
}
@@ -726,6 +728,7 @@ class _SelectableTextState extends State implements TextSelectio
cursorOffset = Offset(iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0);
case TargetPlatform.android:
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
forcePressEnabled = false;
textSelectionControls ??= materialTextSelectionHandleControls;
diff --git a/packages/flutter/lib/src/material/selection_area.dart b/packages/flutter/lib/src/material/selection_area.dart
index 2865c74416387c9e6c175ba69b4d2bd439f4298b..f82c7fc94fb44d199035565d27b1449fc332bae1 100644
--- a/packages/flutter/lib/src/material/selection_area.dart
+++ b/packages/flutter/lib/src/material/selection_area.dart
@@ -116,7 +116,7 @@ class _SelectionAreaState extends State {
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
final TextSelectionControls controls = widget.selectionControls ?? switch (Theme.of(context).platform) {
- TargetPlatform.android || TargetPlatform.fuchsia => materialTextSelectionHandleControls,
+ TargetPlatform.android || TargetPlatform.fuchsia || TargetPlatform.ohos => materialTextSelectionHandleControls,
TargetPlatform.linux || TargetPlatform.windows => desktopTextSelectionHandleControls,
TargetPlatform.iOS => cupertinoTextSelectionHandleControls,
TargetPlatform.macOS => cupertinoDesktopTextSelectionHandleControls,
diff --git a/packages/flutter/lib/src/material/slider.dart b/packages/flutter/lib/src/material/slider.dart
index 923eb131f11678eeccfc1237a07254baad43b98e..c8739ebd99f30944092095193f852fc770f25101 100644
--- a/packages/flutter/lib/src/material/slider.dart
+++ b/packages/flutter/lib/src/material/slider.dart
@@ -759,6 +759,7 @@ class _SliderState extends State with TickerProviderStateMixin {
final ThemeData theme = Theme.of(context);
switch (theme.platform) {
case TargetPlatform.android:
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
@@ -860,6 +861,7 @@ class _SliderState extends State with TickerProviderStateMixin {
case TargetPlatform.iOS:
case TargetPlatform.linux:
case TargetPlatform.macOS:
+ case TargetPlatform.ohos:
break;
case TargetPlatform.windows:
handleDidGainAccessibilityFocus = () {
@@ -1395,6 +1397,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
return 0.1;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
+ case TargetPlatform.ohos:
case TargetPlatform.linux:
case TargetPlatform.windows:
// Matches Android implementation of material slider.
diff --git a/packages/flutter/lib/src/material/switch.dart b/packages/flutter/lib/src/material/switch.dart
index 35a3dae5507e99a6aeddf6b1027931cb0f47fe9f..3c68d39a02472591d9ded6d482a6a3b73795cc1f 100644
--- a/packages/flutter/lib/src/material/switch.dart
+++ b/packages/flutter/lib/src/material/switch.dart
@@ -586,6 +586,7 @@ class Switch extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
effectiveActiveThumbColor = activeColor;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -715,6 +716,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
updateCurve();
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -787,6 +789,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return widget.size.width - _kSwitchMinSize;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -875,6 +878,7 @@ class _MaterialSwitchState extends State<_MaterialSwitch> with TickerProviderSta
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
switchConfig = theme.useMaterial3 ? _SwitchConfigM3(context) : _SwitchConfigM2();
defaults = theme.useMaterial3 ? _SwitchDefaultsM3(context) : _SwitchDefaultsM2(context);
case TargetPlatform.iOS:
@@ -1751,6 +1755,7 @@ class _SwitchThemeAdaptation extends Adaptation {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return defaultValue;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart
index 99822ef0fac7895e3c61183ccd4dce81c2778af1..c15819e4c8b9a2653564b3d167a95fefdaaaeaaa 100644
--- a/packages/flutter/lib/src/material/text_field.dart
+++ b/packages/flutter/lib/src/material/text_field.dart
@@ -85,6 +85,7 @@ class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDete
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
Feedback.forLongPress(_state.context);
}
}
@@ -888,6 +889,7 @@ class TextField extends StatefulWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
return SpellCheckSuggestionsToolbar.editableText(
editableTextState: editableTextState,
);
@@ -1237,7 +1239,9 @@ class _TextFieldState extends State with RestorationMixin implements
case TargetPlatform.windows:
case TargetPlatform.fuchsia:
case TargetPlatform.android:
- if (cause == SelectionChangedCause.longPress) {
+ case TargetPlatform.ohos:
+ if (cause == SelectionChangedCause.longPress
+ || cause == SelectionChangedCause.drag) {
_editableText?.bringIntoView(selection.extent);
}
}
@@ -1246,6 +1250,7 @@ class _TextFieldState extends State with RestorationMixin implements
case TargetPlatform.iOS:
case TargetPlatform.fuchsia:
case TargetPlatform.android:
+ case TargetPlatform.ohos:
break;
case TargetPlatform.macOS:
case TargetPlatform.linux:
@@ -1365,6 +1370,7 @@ class _TextFieldState extends State with RestorationMixin implements
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
spellCheckConfiguration = TextField.inferAndroidSpellCheckConfiguration(
widget.spellCheckConfiguration,
);
@@ -1416,13 +1422,14 @@ class _TextFieldState extends State with RestorationMixin implements
case TargetPlatform.android:
case TargetPlatform.fuchsia:
+ case TargetPlatform.ohos:
forcePressEnabled = false;
textSelectionControls ??= materialTextSelectionHandleControls;
paintCursorAboveText = false;
cursorOpacityAnimates ??= false;
cursorColor = _hasError ? _errorColor : widget.cursorColor ?? selectionStyle.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionStyle.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
-
+ break;
case TargetPlatform.linux:
forcePressEnabled = false;
textSelectionControls ??= desktopTextSelectionHandleControls;
diff --git a/packages/flutter/lib/src/material/text_selection_toolbar.dart b/packages/flutter/lib/src/material/text_selection_toolbar.dart
index 96f00227cf8767213fc0f7414573253ddde45308..2ced3cfb707f6729c3f4791520caa614087b42d6 100644
--- a/packages/flutter/lib/src/material/text_selection_toolbar.dart
+++ b/packages/flutter/lib/src/material/text_selection_toolbar.dart
@@ -17,6 +17,8 @@ import 'material_localizations.dart';
import 'theme.dart';
const double _kToolbarHeight = 44.0;
+
+// Padding between the toolbar and the anchor.
const double _kToolbarContentDistance = 8.0;
/// A fully-functional Material-style text selection toolbar.
diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart
index 1378bdfc3e968d77970e147ea8f26dbdbad9c386..6cd341993187f0281db6a9ec69d0da00d025b1e6 100644
--- a/packages/flutter/lib/src/material/theme_data.dart
+++ b/packages/flutter/lib/src/material/theme_data.dart
@@ -377,6 +377,7 @@ class ThemeData with Diagnosticable {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
+ case TargetPlatform.ohos:
materialTapTargetSize ??= MaterialTapTargetSize.padded;
case TargetPlatform.linux:
case TargetPlatform.macOS:
@@ -2366,7 +2367,7 @@ class VisualDensity with Diagnosticable {
/// adaptive based on [defaultTargetPlatform].
static VisualDensity defaultDensityForPlatform(TargetPlatform platform) {
return switch (platform) {
- TargetPlatform.android || TargetPlatform.iOS || TargetPlatform.fuchsia => standard,
+ TargetPlatform.android || TargetPlatform.iOS || TargetPlatform.fuchsia || TargetPlatform.ohos => standard,
TargetPlatform.linux || TargetPlatform.macOS || TargetPlatform.windows => compact,
};
}
diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart
index 1fe8d502c43df78f1fbf3377f7a6ef51a8407b76..b4790b25567964314530fafe098241d20a4e69c9 100644
--- a/packages/flutter/lib/src/material/time_picker.dart
+++ b/packages/flutter/lib/src/material/time_picker.dart
@@ -563,6 +563,7 @@ class _DayPeriodControl extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
_announceToAccessibility(context, MaterialLocalizations.of(context).anteMeridiemAbbreviation);
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -581,6 +582,7 @@ class _DayPeriodControl extends StatelessWidget {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
_announceToAccessibility(context, MaterialLocalizations.of(context).postMeridiemAbbreviation);
case TargetPlatform.iOS:
case TargetPlatform.macOS:
@@ -2658,6 +2660,7 @@ class _TimePickerState extends State<_TimePicker> with RestorationMixin {
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
_vibrateTimer?.cancel();
_vibrateTimer = Timer(_kVibrateCommitDelay, () {
HapticFeedback.vibrate();
diff --git a/packages/flutter/lib/src/material/tooltip.dart b/packages/flutter/lib/src/material/tooltip.dart
index 4431019283dc1ba6e4279655e1a029e95ff330ea..dee828c7921ab0640774dbbbdf3939db3a56ae91 100644
--- a/packages/flutter/lib/src/material/tooltip.dart
+++ b/packages/flutter/lib/src/material/tooltip.dart
@@ -740,7 +740,8 @@ class TooltipState extends State with SingleTickerProviderStateMixin {
TargetPlatform.windows => 24.0,
TargetPlatform.android ||
TargetPlatform.fuchsia ||
- TargetPlatform.iOS => 32.0,
+ TargetPlatform.iOS ||
+ TargetPlatform.ohos => 32.0,
};
}
@@ -751,7 +752,8 @@ class TooltipState extends State with SingleTickerProviderStateMixin {
TargetPlatform.windows => const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
TargetPlatform.android ||
TargetPlatform.fuchsia ||
- TargetPlatform.iOS => const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
+ TargetPlatform.iOS ||
+ TargetPlatform.ohos => const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
};
}
@@ -762,7 +764,8 @@ class TooltipState extends State with SingleTickerProviderStateMixin {
TargetPlatform.windows => 12.0,
TargetPlatform.android ||
TargetPlatform.fuchsia ||
- TargetPlatform.iOS => 14.0,
+ TargetPlatform.iOS ||
+ TargetPlatform.ohos => 14.0,
};
}
diff --git a/packages/flutter/lib/src/material/typography.dart b/packages/flutter/lib/src/material/typography.dart
index 771c4f6e20dfff1b1bd6da515439e78af088858f..4faae73944d397057fb29df3ef1781034faca380 100644
--- a/packages/flutter/lib/src/material/typography.dart
+++ b/packages/flutter/lib/src/material/typography.dart
@@ -228,6 +228,11 @@ class Typography with Diagnosticable {
case TargetPlatform.linux:
black ??= blackHelsinki;
white ??= whiteHelsinki;
+ break;
+ case TargetPlatform.ohos:
+ black ??= blackHelsinki;
+ white ??= whiteHelsinki;
+ break;
case null:
break;
}
diff --git a/packages/flutter/lib/src/painting/flutter_logo.dart b/packages/flutter/lib/src/painting/flutter_logo.dart
index ecbdffd06164bda18464d32d1cecce102991b04a..fbdb4f6d311b61f75aeeb92c2350d0fc2f4f0a5b 100644
--- a/packages/flutter/lib/src/painting/flutter_logo.dart
+++ b/packages/flutter/lib/src/painting/flutter_logo.dart
@@ -240,7 +240,8 @@ class _FlutterLogoPainter extends BoxPainter {
textDirection: TextDirection.ltr,
);
_textPainter.layout();
- final ui.TextBox textSize = _textPainter.getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: kLabel.length)).single;
+ final List boxList = _textPainter.getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: kLabel.length));
+ final ui.TextBox textSize = boxList.isNotEmpty ? boxList.single : ui.TextBox.fromLTRBD(0, 0, 0, 0, TextDirection.ltr);
_textBoundingRect = Rect.fromLTRB(textSize.left, textSize.top, textSize.right, textSize.bottom);
}
diff --git a/packages/flutter/lib/src/rendering/editable.dart b/packages/flutter/lib/src/rendering/editable.dart
index becab81f7a31b41315f236707707a105f653022d..85b684ef22f59c071e441b60c94f2840607f51cc 100644
--- a/packages/flutter/lib/src/rendering/editable.dart
+++ b/packages/flutter/lib/src/rendering/editable.dart
@@ -1811,6 +1811,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
// Override the height to take the full height of the glyph at the TextPosition
// when not on iOS. iOS has special handling that creates a taller caret.
// TODO(garyq): See the TODO for _computeCaretPrototype().
@@ -2205,6 +2206,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
extentOffset: position.offset,
);
}
+ break;
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
case TargetPlatform.macOS:
case TargetPlatform.linux:
@@ -2272,6 +2275,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
+ case TargetPlatform.ohos:
_caretPrototype = Rect.fromLTWH(0.0, _kCaretHeightOffset, cursorWidth, cursorHeight - 2.0 * _kCaretHeightOffset);
}
}
diff --git a/packages/flutter/lib/src/rendering/platform_view.dart b/packages/flutter/lib/src/rendering/platform_view.dart
index 77866294bdbc5ad67b834e84b15fb106d62b8f13..39c1b0256e9ce3fb1e940a716843970bcc6f661f 100644
--- a/packages/flutter/lib/src/rendering/platform_view.dart
+++ b/packages/flutter/lib/src/rendering/platform_view.dart
@@ -270,6 +270,209 @@ class RenderAndroidView extends PlatformViewRenderBox {
}
}
+class RenderOhosView extends PlatformViewRenderBox {
+ /// Creates a render object for an Ohos view.
+ RenderOhosView({
+ required OhosViewController viewController,
+ required PlatformViewHitTestBehavior hitTestBehavior,
+ required Set> gestureRecognizers,
+ Clip clipBehavior = Clip.hardEdge,
+ }) : assert(viewController != null),
+ assert(hitTestBehavior != null),
+ assert(gestureRecognizers != null),
+ assert(clipBehavior != null),
+ _viewController = viewController,
+ _clipBehavior = clipBehavior,
+ super(controller: viewController, hitTestBehavior: hitTestBehavior, gestureRecognizers: gestureRecognizers) {
+ _viewController.pointTransformer = (Offset offset) => globalToLocal(offset);
+ updateGestureRecognizers(gestureRecognizers);
+ _viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated);
+ this.hitTestBehavior = hitTestBehavior;
+ _setOffset();
+ }
+
+ _PlatformViewState _state = _PlatformViewState.uninitialized;
+
+ Size? _currentTextureSize;
+
+ bool _isDisposed = false;
+
+ /// The Ohos view controller for the Ohos view associated with this render object.
+ @override
+ OhosViewController get controller => _viewController;
+
+ OhosViewController _viewController;
+
+ /// Sets a new Ohos view controller.
+ @override
+ set controller(OhosViewController controller) {
+ assert(!_isDisposed);
+ assert(_viewController != null);
+ assert(controller != null);
+ if (_viewController == controller) {
+ return;
+ }
+ _viewController.removeOnPlatformViewCreatedListener(_onPlatformViewCreated);
+ super.controller = controller;
+ _viewController = controller;
+ _viewController.pointTransformer = (Offset offset) => globalToLocal(offset);
+ _sizePlatformView();
+ if (_viewController.isCreated) {
+ markNeedsSemanticsUpdate();
+ }
+ _viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated);
+ }
+
+ /// {@macro flutter.material.Material.clipBehavior}
+ ///
+ /// Defaults to [Clip.hardEdge], and must not be null.
+ Clip get clipBehavior => _clipBehavior;
+ Clip _clipBehavior = Clip.hardEdge;
+ set clipBehavior(Clip value) {
+ assert(value != null);
+ if (value != _clipBehavior) {
+ _clipBehavior = value;
+ markNeedsPaint();
+ markNeedsSemanticsUpdate();
+ }
+ }
+
+ void _onPlatformViewCreated(int id) {
+ assert(!_isDisposed);
+ markNeedsSemanticsUpdate();
+ }
+
+ @override
+ bool get sizedByParent => true;
+
+ @override
+ bool get alwaysNeedsCompositing => true;
+
+ @override
+ bool get isRepaintBoundary => true;
+
+ @override
+ Size computeDryLayout(BoxConstraints constraints) {
+ return constraints.biggest;
+ }
+
+ @override
+ void performResize() {
+ super.performResize();
+ _sizePlatformView();
+ }
+
+ Future _sizePlatformView() async {
+ // Ohos virtual displays cannot have a zero size.
+ // Trying to size it to 0 crashes the app, which was happening when starting the app
+ // with a locked screen (see: https://github.com/flutter/flutter/issues/20456).
+ if (_state == _PlatformViewState.resizing || size.isEmpty) {
+ return;
+ }
+
+ _state = _PlatformViewState.resizing;
+ markNeedsPaint();
+
+ Size targetSize;
+ do {
+ targetSize = size;
+ _currentTextureSize = await _viewController.setSize(targetSize);
+ if (_isDisposed) {
+ return;
+ }
+ // We've resized the platform view to targetSize, but it is possible that
+ // while we were resizing the render object's size was changed again.
+ // In that case we will resize the platform view again.
+ } while (size != targetSize);
+
+ _state = _PlatformViewState.ready;
+ markNeedsPaint();
+ }
+
+ // Sets the offset of the underlying platform view on the platform side.
+ //
+ // This allows the Ohos native view to draw the a11y highlights in the same
+ // location on the screen as the platform view widget in the Flutter framework.
+ //
+ // It also allows platform code to obtain the correct position of the Ohos
+ // native view on the screen.
+ void _setOffset() {
+ SchedulerBinding.instance.addPostFrameCallback((_) async {
+ if (!_isDisposed) {
+ if (attached) {
+ await _viewController.setOffset(localToGlobal(Offset.zero));
+ }
+ // Schedule a new post frame callback.
+ _setOffset();
+ }
+ });
+ }
+
+ @override
+ void paint(PaintingContext context, Offset offset) {
+ if (_viewController.textureId == null || _currentTextureSize == null) {
+ return;
+ }
+
+ // As resizing the Ohos view happens asynchronously we don't know exactly when is a
+ // texture frame with the new size is ready for consumption.
+ // TextureLayer is unaware of the texture frame's size and always maps it to the
+ // specified rect. If the rect we provide has a different size from the current texture frame's
+ // size the texture frame will be scaled.
+ // To prevent unwanted scaling artifacts while resizing, clip the texture.
+ // This guarantees that the size of the texture frame we're painting is always
+ // _currentOhosTextureSize.
+ final bool isTextureLargerThanWidget = _currentTextureSize!.width > size.width ||
+ _currentTextureSize!.height > size.height;
+ if (isTextureLargerThanWidget && clipBehavior != Clip.none) {
+ _clipRectLayer.layer = context.pushClipRect(
+ true,
+ offset,
+ offset & size,
+ _paintTexture,
+ clipBehavior: clipBehavior,
+ oldLayer: _clipRectLayer.layer,
+ );
+ return;
+ }
+ _clipRectLayer.layer = null;
+ _paintTexture(context, offset);
+ }
+
+ final LayerHandle _clipRectLayer = LayerHandle();
+
+ @override
+ void dispose() {
+ _isDisposed = true;
+ _clipRectLayer.layer = null;
+ _viewController.removeOnPlatformViewCreatedListener(_onPlatformViewCreated);
+ super.dispose();
+ }
+
+ void _paintTexture(PaintingContext context, Offset offset) {
+ if (_currentTextureSize == null) {
+ return;
+ }
+
+ context.addLayer(TextureLayer(
+ rect: offset & _currentTextureSize!,
+ textureId: _viewController.textureId!,
+ ));
+ }
+
+ @override
+ void describeSemanticsConfiguration(SemanticsConfiguration config) {
+ // Don't call the super implementation since `platformViewId` should
+ // be set only when the platform view is created, but the concept of
+ // a "created" platform view belongs to this subclass.
+ config.isSemanticBoundary = true;
+
+ if (_viewController.isCreated) {
+ config.platformViewId = _viewController.viewId;
+ }
+ }
+}
+
/// Common render-layer functionality for iOS and macOS platform views.
///
/// Provides the basic rendering logic for iOS and macOS platformviews.
diff --git a/packages/flutter/lib/src/rendering/view.dart b/packages/flutter/lib/src/rendering/view.dart
index c4842cfc00af57d78c392c3497b1cdb84c32e742..914e4da08cdd56cc980af539ac19cfc7eb4435b9 100644
--- a/packages/flutter/lib/src/rendering/view.dart
+++ b/packages/flutter/lib/src/rendering/view.dart
@@ -378,6 +378,8 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin
switch (defaultTargetPlatform) {
case TargetPlatform.android:
lowerOverlayStyle = layer!.find(bottom);
+ break;
+ case TargetPlatform.ohos:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
case TargetPlatform.linux:
diff --git a/packages/flutter/lib/src/services/binding.dart b/packages/flutter/lib/src/services/binding.dart
index e6105ed6537f684abedf359afaa6a0ff94daca9a..134f7f888e1d71dda58eb090003920aa0d52c745 100644
--- a/packages/flutter/lib/src/services/binding.dart
+++ b/packages/flutter/lib/src/services/binding.dart
@@ -159,6 +159,9 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
@mustCallSuper
Future handleSystemMessage(Object systemMessage) async {
final Map message = systemMessage as Map;
+ if (message['type'] is! String) {
+ return;
+ }
final String type = message['type'] as String;
switch (type) {
case 'memoryPressure':
diff --git a/packages/flutter/lib/src/services/keyboard_key.g.dart b/packages/flutter/lib/src/services/keyboard_key.g.dart
index 4feaa7b0ad42181f0ba8a2f916daee633d46efb5..e83fd9bd017191e6e199dd296561e834e4a80cff 100644
--- a/packages/flutter/lib/src/services/keyboard_key.g.dart
+++ b/packages/flutter/lib/src/services/keyboard_key.g.dart
@@ -341,6 +341,12 @@ class LogicalKeyboardKey extends KeyboardKey {
/// This is used by platform-specific code to generate Flutter key codes.
static const int glfwPlane = 0x01800000000;
+ /// The plane value for the private keys defined by the ohos embedding.
+ ///
+ /// This is used by platform-specific code to generate Flutter key codes.
+ static const int ohosPlane = 0x01900000000;
+
+
/// Represents the logical "Space" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
diff --git a/packages/flutter/lib/src/services/keyboard_maps.g.dart b/packages/flutter/lib/src/services/keyboard_maps.g.dart
index b94e1c82e532678ad0dbe8a379ad6765ccee57ac..cbba13388bace800df3f10120b4d90bd3c690740 100644
--- a/packages/flutter/lib/src/services/keyboard_maps.g.dart
+++ b/packages/flutter/lib/src/services/keyboard_maps.g.dart
@@ -538,6 +538,651 @@ const Map kAndroidNumPadMap =
163: LogicalKeyboardKey.numpadParenRight,
};
+/// Maps Ohos-specific key codes to the matching [LogicalKeyboardKey].
+const Map kOhosToLogicalKey = {
+ 2000: LogicalKeyboardKey.digit0,
+ 2001: LogicalKeyboardKey.digit1,
+ 2002: LogicalKeyboardKey.digit2,
+ 2003: LogicalKeyboardKey.digit3,
+ 2004: LogicalKeyboardKey.digit4,
+ 2005: LogicalKeyboardKey.digit5,
+ 2006: LogicalKeyboardKey.digit6,
+ 2007: LogicalKeyboardKey.digit7,
+ 2008: LogicalKeyboardKey.digit8,
+ 2009: LogicalKeyboardKey.digit9,
+ 2010: LogicalKeyboardKey.asterisk,
+ 2011: LogicalKeyboardKey.numberSign,
+ 2012: LogicalKeyboardKey.arrowUp,
+ 2013: LogicalKeyboardKey.arrowDown,
+ 2014: LogicalKeyboardKey.arrowLeft,
+ 2015: LogicalKeyboardKey.arrowRight,
+ //2016: LogicalKeyboardKey.dpadCenter,
+ 2017: LogicalKeyboardKey.keyA,
+ 2018: LogicalKeyboardKey.keyB,
+ 2019: LogicalKeyboardKey.keyC,
+ 2020: LogicalKeyboardKey.keyD,
+ 2021: LogicalKeyboardKey.keyE,
+ 2022: LogicalKeyboardKey.keyF,
+ 2023: LogicalKeyboardKey.keyG,
+ 2024: LogicalKeyboardKey.keyH,
+ 2025: LogicalKeyboardKey.keyI,
+ 2026: LogicalKeyboardKey.keyJ,
+ 2027: LogicalKeyboardKey.keyK,
+ 2028: LogicalKeyboardKey.keyL,
+ 2029: LogicalKeyboardKey.keyM,
+ 2030: LogicalKeyboardKey.keyN,
+ 2031: LogicalKeyboardKey.keyO,
+ 2032: LogicalKeyboardKey.keyP,
+ 2033: LogicalKeyboardKey.keyQ,
+ 2034: LogicalKeyboardKey.keyR,
+ 2035: LogicalKeyboardKey.keyS,
+ 2036: LogicalKeyboardKey.keyT,
+ 2037: LogicalKeyboardKey.keyU,
+ 2038: LogicalKeyboardKey.keyV,
+ 2039: LogicalKeyboardKey.keyW,
+ 2040: LogicalKeyboardKey.keyX,
+ 2041: LogicalKeyboardKey.keyY,
+ 2042: LogicalKeyboardKey.keyZ,
+ 2043: LogicalKeyboardKey.comma,
+ 2044: LogicalKeyboardKey.period,
+ 2045: LogicalKeyboardKey.altLeft,
+ 2046: LogicalKeyboardKey.altRight,
+ 2047: LogicalKeyboardKey.shiftLeft,
+ 2048: LogicalKeyboardKey.shiftRight,
+ 2049: LogicalKeyboardKey.tab,
+ 2050: LogicalKeyboardKey.space,
+ 2052: LogicalKeyboardKey.launchWebBrowser,
+ 2053: LogicalKeyboardKey.launchMail,
+ 2054: LogicalKeyboardKey.enter,
+ 2055: LogicalKeyboardKey.backspace,
+ 2056: LogicalKeyboardKey.backquote,
+ 2057: LogicalKeyboardKey.minus,
+ 2058: LogicalKeyboardKey.equal,
+ 2059: LogicalKeyboardKey.bracketLeft,
+ 2060: LogicalKeyboardKey.bracketRight,
+ 2061: LogicalKeyboardKey.backslash,
+ 2062: LogicalKeyboardKey.semicolon,
+ 2063: LogicalKeyboardKey.quote,
+ 2064: LogicalKeyboardKey.slash,
+ 2067: LogicalKeyboardKey.contextMenu,
+ 2466: LogicalKeyboardKey.compose,
+ 2068: LogicalKeyboardKey.pageUp,
+ 2069: LogicalKeyboardKey.pageDown,
+ 2070: LogicalKeyboardKey.escape,
+ 2071: LogicalKeyboardKey.delete,
+ 2072: LogicalKeyboardKey.controlLeft,
+ 2073: LogicalKeyboardKey.controlRight,
+ 2074: LogicalKeyboardKey.capsLock,
+ 2075: LogicalKeyboardKey.scrollLock,
+ 2076: LogicalKeyboardKey.metaLeft,
+ 2077: LogicalKeyboardKey.metaRight,
+ 2078: LogicalKeyboardKey.fn,
+ 2079: LogicalKeyboardKey.printScreen,
+ 2080: LogicalKeyboardKey.pause,
+ 2081: LogicalKeyboardKey.home,
+ 2082: LogicalKeyboardKey.end,
+ 2083: LogicalKeyboardKey.insert,
+ 2084: LogicalKeyboardKey.browserForward,
+ 2085: LogicalKeyboardKey.mediaPlay,
+ 2643: LogicalKeyboardKey.play,
+ 2086: LogicalKeyboardKey.mediaPause,
+ 2087: LogicalKeyboardKey.mediaClose,
+ 2088: LogicalKeyboardKey.eject,
+ 2089: LogicalKeyboardKey.mediaRecord,
+ 2090: LogicalKeyboardKey.f1,
+ 2091: LogicalKeyboardKey.f2,
+ 2092: LogicalKeyboardKey.f3,
+ 2093: LogicalKeyboardKey.f4,
+ 2094: LogicalKeyboardKey.f5,
+ 2095: LogicalKeyboardKey.f6,
+ 2096: LogicalKeyboardKey.f7,
+ 2097: LogicalKeyboardKey.f8,
+ 2098: LogicalKeyboardKey.f9,
+ 2099: LogicalKeyboardKey.f10,
+ 2100: LogicalKeyboardKey.f11,
+ 2101: LogicalKeyboardKey.f12,
+ 2102: LogicalKeyboardKey.numLock,
+ 2103: LogicalKeyboardKey.numpad0,
+ 2104: LogicalKeyboardKey.numpad1,
+ 2105: LogicalKeyboardKey.numpad2,
+ 2106: LogicalKeyboardKey.numpad3,
+ 2107: LogicalKeyboardKey.numpad4,
+ 2108: LogicalKeyboardKey.numpad5,
+ 2109: LogicalKeyboardKey.numpad6,
+ 2110: LogicalKeyboardKey.numpad7,
+ 2111: LogicalKeyboardKey.numpad8,
+ 2112: LogicalKeyboardKey.numpad9,
+ 2113: LogicalKeyboardKey.numpadDivide,
+ 2114: LogicalKeyboardKey.numpadMultiply,
+ 2115: LogicalKeyboardKey.numpadSubtract,
+ 2116: LogicalKeyboardKey.numpadAdd,
+ 2117: LogicalKeyboardKey.numpadDecimal,
+ 2118: LogicalKeyboardKey.numpadComma,
+ 2119: LogicalKeyboardKey.numpadEnter,
+ 2120: LogicalKeyboardKey.numpadEqual,
+ 2121: LogicalKeyboardKey.numpadParenLeft,
+ 2122: LogicalKeyboardKey.numpadParenRight,
+ 16: LogicalKeyboardKey.audioVolumeUp,
+ 17: LogicalKeyboardKey.audioVolumeDown,
+ 18: LogicalKeyboardKey.power,
+ 22: LogicalKeyboardKey.microphoneVolumeMute,
+ 1: LogicalKeyboardKey.home,
+ 2: LogicalKeyboardKey.goBack,
+// 2210: LogicalKeyboardKey.virtualMultitask,
+// 2301: LogicalKeyboardKey.buttonA,
+// 2302: LogicalKeyboardKey.buttonB,
+// 2303: LogicalKeyboardKey.buttonC,
+// 2304: LogicalKeyboardKey.buttonX,
+// 2305: LogicalKeyboardKey.buttonY,
+// 2306: LogicalKeyboardKey.buttonZ,
+// 2307: LogicalKeyboardKey.buttonL1,
+// 2308: LogicalKeyboardKey.buttonR1,
+// 2309: LogicalKeyboardKey.buttonL2,
+// 2310: LogicalKeyboardKey.buttonR2,
+// 2311: LogicalKeyboardKey.buttonSelect,
+// 2312: LogicalKeyboardKey.buttonStart,
+// 2313: LogicalKeyboardKey.buttonMode,
+// 2314: LogicalKeyboardKey.buttonThumbl,
+// 2315: LogicalKeyboardKey.buttonThumbr,
+// 2401: LogicalKeyboardKey.buttonTrigger,
+// 2402: LogicalKeyboardKey.buttonThumb,
+// 2403: LogicalKeyboardKey.buttonThumb2,
+// 2404: LogicalKeyboardKey.buttonTop,
+// 2405: LogicalKeyboardKey.buttonTop2,
+// 2406: LogicalKeyboardKey.buttonPinkie,
+// 2407: LogicalKeyboardKey.buttonBase1,
+// 2408: LogicalKeyboardKey.buttonBase2,
+// 2409: LogicalKeyboardKey.buttonBase3,
+// 2410: LogicalKeyboardKey.buttonBase4,
+// 2411: LogicalKeyboardKey.buttonBase5,
+// 2412: LogicalKeyboardKey.buttonBase6,
+// 2413: LogicalKeyboardKey.buttonBase7,
+// 2414: LogicalKeyboardKey.buttonBase8,
+// 2415: LogicalKeyboardKey.buttonBase9,
+// 2416: LogicalKeyboardKey.buttonDead,
+ 19: LogicalKeyboardKey.camera,
+ 40: LogicalKeyboardKey.brightnessUp,
+ 41: LogicalKeyboardKey.brightnessDown,
+ 5: LogicalKeyboardKey.clear,
+// 7: LogicalKeyboardKey.focus,
+// 9: LogicalKeyboardKey.search,
+ 10: LogicalKeyboardKey.mediaPlayPause,
+ 11: LogicalKeyboardKey.mediaStop,
+ 12: LogicalKeyboardKey.mediaTrackNext,
+ 13: LogicalKeyboardKey.mediaTrackPrevious,
+ 14: LogicalKeyboardKey.mediaRewind,
+ 15: LogicalKeyboardKey.mediaFastForward,
+// 20: LogicalKeyboardKey.voiceAssistant,
+// -1: LogicalKeyboardKey.unknown,
+ 2600: LogicalKeyboardKey.sleep,
+ 2601: LogicalKeyboardKey.zenkakuHankaku,
+// 2602: LogicalKeyboardKey.102nd,
+// 2603: LogicalKeyboardKey.ro,
+ 2604: LogicalKeyboardKey.katakana,
+ 2605: LogicalKeyboardKey.hiragana,
+ 2606: LogicalKeyboardKey.convert,
+ 2607: LogicalKeyboardKey.hiraganaKatakana,
+ 2608: LogicalKeyboardKey.nonConvert,
+// 2609: LogicalKeyboardKey.linefeed,
+// 2610: LogicalKeyboardKey.macro,
+// 2611: LogicalKeyboardKey.numpadPlusminus,
+// 2612: LogicalKeyboardKey.scale,
+// 2613: LogicalKeyboardKey.hanguel,
+// 2614: LogicalKeyboardKey.hanja,
+ 2615: LogicalKeyboardKey.intlYen,
+// 2616: LogicalKeyboardKey.stop,
+ 2617: LogicalKeyboardKey.again,
+ 2618: LogicalKeyboardKey.props,
+ 2619: LogicalKeyboardKey.undo,
+ 2620: LogicalKeyboardKey.copy,
+ 2621: LogicalKeyboardKey.open,
+ 2622: LogicalKeyboardKey.paste,
+ 2623: LogicalKeyboardKey.find,
+ 2624: LogicalKeyboardKey.cut,
+ 2625: LogicalKeyboardKey.help,
+// 2626: LogicalKeyboardKey.calc,
+// 2627: LogicalKeyboardKey.file,
+ 2628: LogicalKeyboardKey.browserFavorites,
+// 12: LogicalKeyboardKey.mediaTrackNext,
+ 2630: LogicalKeyboardKey.mediaPlayPause,
+// 13: LogicalKeyboardKey.mediaTrackPrevious,
+ 2632: LogicalKeyboardKey.close,
+ 3: LogicalKeyboardKey.call,
+// 2634: LogicalKeyboardKey.config,
+ 2635: LogicalKeyboardKey.browserRefresh,
+ 2636: LogicalKeyboardKey.exit,
+// 2637: LogicalKeyboardKey.edit,
+// 2638: LogicalKeyboardKey.scrollup,
+// 2639: LogicalKeyboardKey.scrolldown,
+// 2640: LogicalKeyboardKey.new,
+ 2641: LogicalKeyboardKey.redo,
+ 2642: LogicalKeyboardKey.close,
+// 2644: LogicalKeyboardKey.bassboost,
+ 2645: LogicalKeyboardKey.print,
+// 2646: LogicalKeyboardKey.chat,
+// 2647: LogicalKeyboardKey.finance,
+ 2648: LogicalKeyboardKey.cancel,
+// 2649: LogicalKeyboardKey.kbdillumToggle,
+// 2650: LogicalKeyboardKey.kbdillumDown,
+// 2651: LogicalKeyboardKey.kbdillumUp,
+// 2652: LogicalKeyboardKey.send,
+// 2653: LogicalKeyboardKey.reply,
+// 2654: LogicalKeyboardKey.forwardmail,
+ 2655: LogicalKeyboardKey.save,
+// 2656: LogicalKeyboardKey.documents,
+// 2657: LogicalKeyboardKey.videoNext,
+// 2658: LogicalKeyboardKey.videoPrev,
+// 2659: LogicalKeyboardKey.brightnessCycle,
+// 2660: LogicalKeyboardKey.brightnessZero,
+// 2661: LogicalKeyboardKey.displayOff,
+// 2663: LogicalKeyboardKey.goto,
+ 2664: LogicalKeyboardKey.info,
+// 2665: LogicalKeyboardKey.program,
+// 2666: LogicalKeyboardKey.pvr,
+ 2667: LogicalKeyboardKey.subtitle,
+// 2668: LogicalKeyboardKey.fullScreen,
+// 2669: LogicalKeyboardKey.keyboard,
+// 2670: LogicalKeyboardKey.aspectRatio,
+// 2671: LogicalKeyboardKey.pc,
+ 2672: LogicalKeyboardKey.tv,
+// 2673: LogicalKeyboardKey.tv2,
+// 2674: LogicalKeyboardKey.vcr,
+// 2675: LogicalKeyboardKey.vcr2,
+// 2676: LogicalKeyboardKey.sat,
+// 2677: LogicalKeyboardKey.cd,
+// 2678: LogicalKeyboardKey.tape,
+// 2679: LogicalKeyboardKey.tuner,
+// 2680: LogicalKeyboardKey.player,
+// 2681: LogicalKeyboardKey.dvd,
+// 2682: LogicalKeyboardKey.audio,
+// 2683: LogicalKeyboardKey.video,
+// 2684: LogicalKeyboardKey.memo,
+// 2685: LogicalKeyboardKey.calendar,
+ 2686: LogicalKeyboardKey.colorF0Red,
+ 2687: LogicalKeyboardKey.colorF1Green,
+ 2688: LogicalKeyboardKey.colorF2Yellow,
+ 2689: LogicalKeyboardKey.colorF3Blue,
+ 2690: LogicalKeyboardKey.channelUp,
+ 2691: LogicalKeyboardKey.channelDown,
+// 2692: LogicalKeyboardKey.last,
+// 2693: LogicalKeyboardKey.restart,
+// 2694: LogicalKeyboardKey.slow,
+// 2695: LogicalKeyboardKey.shuffle,
+// 2696: LogicalKeyboardKey.videophone,
+// 2697: LogicalKeyboardKey.games,
+ 2698: LogicalKeyboardKey.zoomIn,
+ 2699: LogicalKeyboardKey.zoomOut,
+// 2700: LogicalKeyboardKey.zoomreset,
+// 2701: LogicalKeyboardKey.wordprocessor,
+// 2702: LogicalKeyboardKey.editor,
+// 2703: LogicalKeyboardKey.spreadsheet,
+// 2704: LogicalKeyboardKey.graphicseditor,
+// 2705: LogicalKeyboardKey.presentation,
+// 2706: LogicalKeyboardKey.database,
+// 2707: LogicalKeyboardKey.news,
+// 2708: LogicalKeyboardKey.voicemail,
+// 2709: LogicalKeyboardKey.addressbook,
+// 2710: LogicalKeyboardKey.messenger,
+// 2711: LogicalKeyboardKey.brightnessToggle,
+ 2712: LogicalKeyboardKey.spellCheck,
+// 2713: LogicalKeyboardKey.coffee,
+// 2714: LogicalKeyboardKey.mediaRepeat,
+// 2715: LogicalKeyboardKey.images,
+// 2716: LogicalKeyboardKey.buttonconfig,
+// 2717: LogicalKeyboardKey.taskmanager,
+// 2718: LogicalKeyboardKey.journal,
+// 2719: LogicalKeyboardKey.controlpanel,
+// 2720: LogicalKeyboardKey.appselect,
+// 2721: LogicalKeyboardKey.screensaver,
+// 2722: LogicalKeyboardKey.assistant,
+// 2723: LogicalKeyboardKey.kbdLayoutNext,
+// 2724: LogicalKeyboardKey.brightnessMin,
+// 2725: LogicalKeyboardKey.brightnessMax,
+// 2726: LogicalKeyboardKey.kbdinputassistPrev,
+// 2727: LogicalKeyboardKey.kbdinputassistNext,
+// 2728: LogicalKeyboardKey.kbdinputassistPrevgroup,
+// 2729: LogicalKeyboardKey.kbdinputassistNextgroup,
+// 2730: LogicalKeyboardKey.kbdinputassistAccept,
+// 2731: LogicalKeyboardKey.kbdinputassistCancel,
+// 2800: LogicalKeyboardKey.front,
+// 2801: LogicalKeyboardKey.setup,
+ 2802: LogicalKeyboardKey.wakeUp,
+// 2803: LogicalKeyboardKey.sendfile,
+// 2804: LogicalKeyboardKey.deletefile,
+// 2805: LogicalKeyboardKey.xfer,
+// 2806: LogicalKeyboardKey.prog1,
+// 2807: LogicalKeyboardKey.prog2,
+// 2808: LogicalKeyboardKey.msdos,
+// 2809: LogicalKeyboardKey.screenlock,
+// 2810: LogicalKeyboardKey.directionRotateDisplay,
+// 2811: LogicalKeyboardKey.cyclewindows,
+// 2812: LogicalKeyboardKey.computer,
+ 2813: LogicalKeyboardKey.eject,
+// 2814: LogicalKeyboardKey.iso,
+// 2815: LogicalKeyboardKey.move,
+ 2816: LogicalKeyboardKey.f13,
+ 2817: LogicalKeyboardKey.f14,
+ 2818: LogicalKeyboardKey.f15,
+ 2819: LogicalKeyboardKey.f16,
+ 2820: LogicalKeyboardKey.f17,
+ 2821: LogicalKeyboardKey.f18,
+ 2822: LogicalKeyboardKey.f19,
+ 2823: LogicalKeyboardKey.f20,
+ 2824: LogicalKeyboardKey.f21,
+ 2825: LogicalKeyboardKey.f22,
+ 2826: LogicalKeyboardKey.f23,
+ 2827: LogicalKeyboardKey.f24,
+// 2828: LogicalKeyboardKey.prog3,
+// 2829: LogicalKeyboardKey.prog4,
+// 2830: LogicalKeyboardKey.dashboard,
+ 2831: LogicalKeyboardKey.suspend,
+// 2832: LogicalKeyboardKey.hp,
+// 2833: LogicalKeyboardKey.sound,
+ 2834: LogicalKeyboardKey.question,
+ 2065: LogicalKeyboardKey.at,
+// 2836: LogicalKeyboardKey.connect,
+// 2837: LogicalKeyboardKey.sport,
+// 2838: LogicalKeyboardKey.shop,
+// 2839: LogicalKeyboardKey.alterase,
+ 6: LogicalKeyboardKey.headsetHook,
+// 2841: LogicalKeyboardKey.switchvideomode,
+// 2842: LogicalKeyboardKey.battery,
+// 2843: LogicalKeyboardKey.bluetooth,
+// 2844: LogicalKeyboardKey.wlan,
+// 2845: LogicalKeyboardKey.uwb,
+// 2846: LogicalKeyboardKey.wwanWimax,
+// 2847: LogicalKeyboardKey.rfkill,
+ 23: LogicalKeyboardKey.audioVolumeMute,
+// 2848: LogicalKeyboardKey.f26,
+// 3001: LogicalKeyboardKey.channel,
+// 3100: LogicalKeyboardKey.btn0,
+// 3101: LogicalKeyboardKey.btn1,
+// 3102: LogicalKeyboardKey.btn2,
+// 3103: LogicalKeyboardKey.btn3,
+// 3104: LogicalKeyboardKey.btn4,
+// 3105: LogicalKeyboardKey.btn5,
+// 3106: LogicalKeyboardKey.btn6,
+// 3107: LogicalKeyboardKey.btn7,
+// 3108: LogicalKeyboardKey.btn8,
+// 3109: LogicalKeyboardKey.btn9,
+// 3201: LogicalKeyboardKey.brlDot1,
+// 3202: LogicalKeyboardKey.brlDot2,
+// 3203: LogicalKeyboardKey.brlDot3,
+// 3204: LogicalKeyboardKey.brlDot4,
+// 3205: LogicalKeyboardKey.brlDot5,
+// 3206: LogicalKeyboardKey.brlDot6,
+// 3207: LogicalKeyboardKey.brlDot7,
+// 3208: LogicalKeyboardKey.brlDot8,
+// 3209: LogicalKeyboardKey.brlDot9,
+// 3210: LogicalKeyboardKey.brlDot10,
+ 4: LogicalKeyboardKey.endCall,
+// 2629: LogicalKeyboardKey.next,
+// 2631: LogicalKeyboardKey.previous,
+};
+
+/// Maps Ohos-specific scan codes to the matching [PhysicalKeyboardKey].
+const Map kOhosToPhysicalKey = {
+ 1: PhysicalKeyboardKey.escape,
+ 2: PhysicalKeyboardKey.digit1,
+ 3: PhysicalKeyboardKey.digit2,
+ 4: PhysicalKeyboardKey.digit3,
+ 5: PhysicalKeyboardKey.digit4,
+ 6: PhysicalKeyboardKey.digit5,
+ 7: PhysicalKeyboardKey.digit6,
+ 8: PhysicalKeyboardKey.digit7,
+ 9: PhysicalKeyboardKey.digit8,
+ 10: PhysicalKeyboardKey.digit9,
+ 11: PhysicalKeyboardKey.digit0,
+ 12: PhysicalKeyboardKey.minus,
+ 13: PhysicalKeyboardKey.equal,
+ 14: PhysicalKeyboardKey.backspace,
+ 15: PhysicalKeyboardKey.tab,
+ 16: PhysicalKeyboardKey.keyQ,
+ 17: PhysicalKeyboardKey.keyW,
+ 18: PhysicalKeyboardKey.keyE,
+ 19: PhysicalKeyboardKey.keyR,
+ 20: PhysicalKeyboardKey.keyT,
+ 21: PhysicalKeyboardKey.keyY,
+ 22: PhysicalKeyboardKey.keyU,
+ 23: PhysicalKeyboardKey.keyI,
+ 24: PhysicalKeyboardKey.keyO,
+ 25: PhysicalKeyboardKey.keyP,
+ 26: PhysicalKeyboardKey.bracketLeft,
+ 27: PhysicalKeyboardKey.bracketRight,
+ 28: PhysicalKeyboardKey.enter,
+ 29: PhysicalKeyboardKey.controlLeft,
+ 30: PhysicalKeyboardKey.keyA,
+ 31: PhysicalKeyboardKey.keyS,
+ 32: PhysicalKeyboardKey.keyD,
+ 33: PhysicalKeyboardKey.keyF,
+ 34: PhysicalKeyboardKey.keyG,
+ 35: PhysicalKeyboardKey.keyH,
+ 36: PhysicalKeyboardKey.keyJ,
+ 37: PhysicalKeyboardKey.keyK,
+ 38: PhysicalKeyboardKey.keyL,
+ 39: PhysicalKeyboardKey.semicolon,
+ 40: PhysicalKeyboardKey.quote,
+ 41: PhysicalKeyboardKey.backquote,
+ 42: PhysicalKeyboardKey.shiftLeft,
+ 43: PhysicalKeyboardKey.backslash,
+ 44: PhysicalKeyboardKey.keyZ,
+ 45: PhysicalKeyboardKey.keyX,
+ 46: PhysicalKeyboardKey.keyC,
+ 47: PhysicalKeyboardKey.keyV,
+ 48: PhysicalKeyboardKey.keyB,
+ 49: PhysicalKeyboardKey.keyN,
+ 50: PhysicalKeyboardKey.keyM,
+ 51: PhysicalKeyboardKey.comma,
+ 52: PhysicalKeyboardKey.period,
+ 53: PhysicalKeyboardKey.slash,
+ 54: PhysicalKeyboardKey.shiftRight,
+ 55: PhysicalKeyboardKey.numpadMultiply,
+ 56: PhysicalKeyboardKey.altLeft,
+ 57: PhysicalKeyboardKey.space,
+ 58: PhysicalKeyboardKey.capsLock,
+ 59: PhysicalKeyboardKey.f1,
+ 60: PhysicalKeyboardKey.f2,
+ 61: PhysicalKeyboardKey.f3,
+ 62: PhysicalKeyboardKey.f4,
+ 63: PhysicalKeyboardKey.f5,
+ 64: PhysicalKeyboardKey.f6,
+ 65: PhysicalKeyboardKey.f7,
+ 66: PhysicalKeyboardKey.f8,
+ 67: PhysicalKeyboardKey.f9,
+ 68: PhysicalKeyboardKey.f10,
+ 69: PhysicalKeyboardKey.numLock,
+ 70: PhysicalKeyboardKey.scrollLock,
+ 71: PhysicalKeyboardKey.numpad7,
+ 72: PhysicalKeyboardKey.numpad8,
+ 73: PhysicalKeyboardKey.numpad9,
+ 74: PhysicalKeyboardKey.numpadSubtract,
+ 75: PhysicalKeyboardKey.numpad4,
+ 76: PhysicalKeyboardKey.numpad5,
+ 77: PhysicalKeyboardKey.numpad6,
+ 78: PhysicalKeyboardKey.numpadAdd,
+ 79: PhysicalKeyboardKey.numpad1,
+ 80: PhysicalKeyboardKey.numpad2,
+ 81: PhysicalKeyboardKey.numpad3,
+ 82: PhysicalKeyboardKey.numpad0,
+ 83: PhysicalKeyboardKey.numpadDecimal,
+ 86: PhysicalKeyboardKey.backslash,
+ 87: PhysicalKeyboardKey.f11,
+ 88: PhysicalKeyboardKey.f12,
+ 89: PhysicalKeyboardKey.intlRo,
+ 90: PhysicalKeyboardKey.lang3,
+ 91: PhysicalKeyboardKey.lang4,
+ 92: PhysicalKeyboardKey.convert,
+ 94: PhysicalKeyboardKey.nonConvert,
+ 95: PhysicalKeyboardKey.numpadComma,
+ 96: PhysicalKeyboardKey.numpadEnter,
+ 97: PhysicalKeyboardKey.controlRight,
+ 98: PhysicalKeyboardKey.numpadDivide,
+ 99: PhysicalKeyboardKey.printScreen,
+ 100: PhysicalKeyboardKey.altRight,
+ 102: PhysicalKeyboardKey.home,
+ 103: PhysicalKeyboardKey.arrowUp,
+ 104: PhysicalKeyboardKey.pageUp,
+ 105: PhysicalKeyboardKey.arrowLeft,
+ 106: PhysicalKeyboardKey.arrowRight,
+ 107: PhysicalKeyboardKey.end,
+ 108: PhysicalKeyboardKey.arrowDown,
+ 109: PhysicalKeyboardKey.pageDown,
+ 110: PhysicalKeyboardKey.insert,
+ 111: PhysicalKeyboardKey.delete,
+ 113: PhysicalKeyboardKey.audioVolumeMute,
+ 114: PhysicalKeyboardKey.audioVolumeDown,
+ 115: PhysicalKeyboardKey.audioVolumeUp,
+ 116: PhysicalKeyboardKey.power,
+ 117: PhysicalKeyboardKey.numpadEqual,
+ 119: PhysicalKeyboardKey.pause,
+ 121: PhysicalKeyboardKey.numpadComma,
+ 124: PhysicalKeyboardKey.intlYen,
+ 125: PhysicalKeyboardKey.metaLeft,
+ 126: PhysicalKeyboardKey.metaRight,
+ 127: PhysicalKeyboardKey.contextMenu,
+ 128: PhysicalKeyboardKey.mediaStop,
+ 129: PhysicalKeyboardKey.again,
+ 130: PhysicalKeyboardKey.props,
+ 131: PhysicalKeyboardKey.undo,
+ 133: PhysicalKeyboardKey.copy,
+ 134: PhysicalKeyboardKey.open,
+ 135: PhysicalKeyboardKey.paste,
+ 136: PhysicalKeyboardKey.find,
+ 137: PhysicalKeyboardKey.cut,
+ 138: PhysicalKeyboardKey.help,
+ 139: PhysicalKeyboardKey.contextMenu,
+ 142: PhysicalKeyboardKey.sleep,
+ 143: PhysicalKeyboardKey.wakeUp,
+ 152: PhysicalKeyboardKey.power,
+ 155: PhysicalKeyboardKey.launchMail,
+ 156: PhysicalKeyboardKey.browserFavorites,
+ 159: PhysicalKeyboardKey.browserForward,
+ 160: PhysicalKeyboardKey.close,
+ 161: PhysicalKeyboardKey.eject,
+ 162: PhysicalKeyboardKey.eject,
+ 163: PhysicalKeyboardKey.mediaTrackNext,
+ 164: PhysicalKeyboardKey.mediaPlayPause,
+ 165: PhysicalKeyboardKey.mediaTrackPrevious,
+ 166: PhysicalKeyboardKey.mediaStop,
+ 167: PhysicalKeyboardKey.mediaRecord,
+ 168: PhysicalKeyboardKey.mediaRewind,
+ 174: PhysicalKeyboardKey.exit,
+ 177: PhysicalKeyboardKey.pageUp,
+ 178: PhysicalKeyboardKey.pageDown,
+ 179: PhysicalKeyboardKey.numpadParenLeft,
+ 180: PhysicalKeyboardKey.numpadParenRight,
+ 182: PhysicalKeyboardKey.redo,
+ 183: PhysicalKeyboardKey.f13,
+ 184: PhysicalKeyboardKey.f14,
+ 185: PhysicalKeyboardKey.f15,
+ 186: PhysicalKeyboardKey.f16,
+ 187: PhysicalKeyboardKey.f17,
+ 188: PhysicalKeyboardKey.f18,
+ 189: PhysicalKeyboardKey.f19,
+ 190: PhysicalKeyboardKey.f20,
+ 191: PhysicalKeyboardKey.f21,
+ 192: PhysicalKeyboardKey.f22,
+ 193: PhysicalKeyboardKey.f23,
+ 194: PhysicalKeyboardKey.f24,
+ 200: PhysicalKeyboardKey.mediaPlay,
+ 201: PhysicalKeyboardKey.mediaPause,
+ 205: PhysicalKeyboardKey.suspend,
+ 206: PhysicalKeyboardKey.close,
+ 207: PhysicalKeyboardKey.mediaPlay,
+ 208: PhysicalKeyboardKey.mediaFastForward,
+ 209: PhysicalKeyboardKey.bassBoost,
+ 210: PhysicalKeyboardKey.print,
+ 215: PhysicalKeyboardKey.launchMail,
+ 217: PhysicalKeyboardKey.browserSearch,
+ 224: PhysicalKeyboardKey.brightnessDown,
+ 225: PhysicalKeyboardKey.brightnessUp,
+ 256: PhysicalKeyboardKey.gameButton1,
+ 257: PhysicalKeyboardKey.gameButton2,
+ 258: PhysicalKeyboardKey.gameButton3,
+ 259: PhysicalKeyboardKey.gameButton4,
+ 260: PhysicalKeyboardKey.gameButton5,
+ 261: PhysicalKeyboardKey.gameButton6,
+ 262: PhysicalKeyboardKey.gameButton7,
+ 263: PhysicalKeyboardKey.gameButton8,
+ 264: PhysicalKeyboardKey.gameButton9,
+ 265: PhysicalKeyboardKey.gameButton10,
+ 266: PhysicalKeyboardKey.gameButton11,
+ 267: PhysicalKeyboardKey.gameButton12,
+ 268: PhysicalKeyboardKey.gameButton13,
+ 269: PhysicalKeyboardKey.gameButton14,
+ 270: PhysicalKeyboardKey.gameButton15,
+ 271: PhysicalKeyboardKey.gameButton16,
+ 288: PhysicalKeyboardKey.gameButton1,
+ 289: PhysicalKeyboardKey.gameButton2,
+ 290: PhysicalKeyboardKey.gameButton3,
+ 291: PhysicalKeyboardKey.gameButton4,
+ 292: PhysicalKeyboardKey.gameButton5,
+ 293: PhysicalKeyboardKey.gameButton6,
+ 294: PhysicalKeyboardKey.gameButton7,
+ 295: PhysicalKeyboardKey.gameButton8,
+ 296: PhysicalKeyboardKey.gameButton9,
+ 297: PhysicalKeyboardKey.gameButton10,
+ 298: PhysicalKeyboardKey.gameButton11,
+ 299: PhysicalKeyboardKey.gameButton12,
+ 300: PhysicalKeyboardKey.gameButton13,
+ 301: PhysicalKeyboardKey.gameButton14,
+ 302: PhysicalKeyboardKey.gameButton15,
+ 303: PhysicalKeyboardKey.gameButton16,
+ 304: PhysicalKeyboardKey.gameButtonA,
+ 305: PhysicalKeyboardKey.gameButtonB,
+ 306: PhysicalKeyboardKey.gameButtonC,
+ 307: PhysicalKeyboardKey.gameButtonX,
+ 308: PhysicalKeyboardKey.gameButtonY,
+ 309: PhysicalKeyboardKey.gameButtonZ,
+ 310: PhysicalKeyboardKey.gameButtonLeft1,
+ 311: PhysicalKeyboardKey.gameButtonRight1,
+ 312: PhysicalKeyboardKey.gameButtonLeft2,
+ 313: PhysicalKeyboardKey.gameButtonRight2,
+ 314: PhysicalKeyboardKey.gameButtonSelect,
+ 315: PhysicalKeyboardKey.gameButtonStart,
+ 316: PhysicalKeyboardKey.gameButtonMode,
+ 317: PhysicalKeyboardKey.gameButtonThumbLeft,
+ 318: PhysicalKeyboardKey.gameButtonThumbRight,
+ 353: PhysicalKeyboardKey.select,
+ 358: PhysicalKeyboardKey.info,
+ 370: PhysicalKeyboardKey.closedCaptionToggle,
+ 397: PhysicalKeyboardKey.launchCalendar,
+ 402: PhysicalKeyboardKey.channelUp,
+ 403: PhysicalKeyboardKey.channelDown,
+ 405: PhysicalKeyboardKey.mediaLast,
+ 411: PhysicalKeyboardKey.pause,
+ 429: PhysicalKeyboardKey.launchContacts,
+ 464: PhysicalKeyboardKey.fn,
+ 583: PhysicalKeyboardKey.launchAssistant,
+};
+
+
+/// A map of Ohos key codes which have printable representations, but appear
+/// on the number pad. Used to provide different key objects for keys like
+/// KEY_EQUALS and NUMPAD_EQUALS.
+const Map kOhosNumPadMap = {
+ 2103: LogicalKeyboardKey.numpad0,
+ 2104: LogicalKeyboardKey.numpad1,
+ 2105: LogicalKeyboardKey.numpad2,
+ 2106: LogicalKeyboardKey.numpad3,
+ 2107: LogicalKeyboardKey.numpad4,
+ 2108: LogicalKeyboardKey.numpad5,
+ 2109: LogicalKeyboardKey.numpad6,
+ 2110: LogicalKeyboardKey.numpad7,
+ 2111: LogicalKeyboardKey.numpad8,
+ 2112: LogicalKeyboardKey.numpad9,
+ 2113: LogicalKeyboardKey.numpadDivide,
+ 2114: LogicalKeyboardKey.numpadMultiply,
+ 2115: LogicalKeyboardKey.numpadSubtract,
+ 2116: LogicalKeyboardKey.numpadAdd,
+ 2117: LogicalKeyboardKey.numpadDecimal,
+ 2118: LogicalKeyboardKey.numpadComma,
+ 2119: LogicalKeyboardKey.numpadEnter,
+ 2120: LogicalKeyboardKey.numpadEqual,
+ 2121: LogicalKeyboardKey.numpadParenLeft,
+ 2122: LogicalKeyboardKey.numpadParenRight,
+};
+
/// Maps Fuchsia-specific IDs to the matching [LogicalKeyboardKey].
const Map kFuchsiaToLogicalKey = {
0x1200000010: LogicalKeyboardKey.hyper,
diff --git a/packages/flutter/lib/src/services/platform_views.dart b/packages/flutter/lib/src/services/platform_views.dart
index 5dbc2008f522d7806a26d2e2a326f46b7083aa97..d188041d3af7d9941cf06022e62ef4873e1705a4 100644
--- a/packages/flutter/lib/src/services/platform_views.dart
+++ b/packages/flutter/lib/src/services/platform_views.dart
@@ -146,6 +146,31 @@ class PlatformViewsService {
return controller;
}
+ static OhosViewController initOhosView({
+ required int id,
+ required String viewType,
+ required TextDirection layoutDirection,
+ dynamic creationParams,
+ MessageCodec? creationParamsCodec,
+ VoidCallback? onFocus,
+ }) {
+ assert(id != null);
+ assert(viewType != null);
+ assert(layoutDirection != null);
+ assert(creationParams == null || creationParamsCodec != null);
+
+ final TextureOhosViewController controller = TextureOhosViewController._(
+ viewId: id,
+ viewType: viewType,
+ layoutDirection: layoutDirection,
+ creationParams: creationParams,
+ creationParamsCodec: creationParamsCodec,
+ );
+
+ _instance._focusCallbacks[id] = onFocus ?? () {};
+ return controller;
+ }
+
/// {@macro flutter.services.PlatformViewsService.initAndroidView}
///
/// This attempts to use the newest and most efficient platform view
@@ -173,6 +198,30 @@ class PlatformViewsService {
return controller;
}
+ static SurfaceOhosViewController initSurfaceOhosView({
+ required int id,
+ required String viewType,
+ required TextDirection layoutDirection,
+ dynamic creationParams,
+ MessageCodec? creationParamsCodec,
+ VoidCallback? onFocus,
+ }) {
+ assert(id != null);
+ assert(viewType != null);
+ assert(layoutDirection != null);
+ assert(creationParams == null || creationParamsCodec != null);
+
+ final SurfaceOhosViewController controller = SurfaceOhosViewController._(
+ viewId: id,
+ viewType: viewType,
+ layoutDirection: layoutDirection,
+ creationParams: creationParams,
+ creationParamsCodec: creationParamsCodec,
+ );
+ _instance._focusCallbacks[id] = onFocus ?? () {};
+ return controller;
+ }
+
/// {@macro flutter.services.PlatformViewsService.initAndroidView}
///
/// When this factory is used, the Android view and Flutter widgets are
@@ -201,6 +250,26 @@ class PlatformViewsService {
return controller;
}
+ static ExpensiveOhosViewController initExpensiveOhosView({
+ required int id,
+ required String viewType,
+ required TextDirection layoutDirection,
+ dynamic creationParams,
+ MessageCodec? creationParamsCodec,
+ VoidCallback? onFocus,
+ }) {
+ final ExpensiveOhosViewController controller = ExpensiveOhosViewController._(
+ viewId: id,
+ viewType: viewType,
+ layoutDirection: layoutDirection,
+ creationParams: creationParams,
+ creationParamsCodec: creationParamsCodec,
+ );
+
+ _instance._focusCallbacks[id] = onFocus ?? () {};
+ return controller;
+ }
+
/// Factory method to create a `UiKitView`.
///
/// The `id` parameter is an unused unique identifier generated with
@@ -334,6 +403,44 @@ class AndroidPointerProperties {
}
}
+class OhosPointerProperties {
+ /// Creates an [OhosPointerProperties] object.
+ ///
+ /// All parameters must not be null.
+ const OhosPointerProperties({
+ required this.id,
+ required this.toolType,
+ }) : assert(id != null),
+ assert(toolType != null);
+
+ final int id;
+
+ /// The type of tool used to make contact such as a finger or stylus, if known.
+ final int toolType;
+
+ /// Value for `toolType` when the tool type is unknown.
+ static const int kToolTypeUnknown = 0;
+
+ /// Value for `toolType` when the tool type is a finger.
+ static const int kToolTypeFinger = 1;
+
+ /// Value for `toolType` when the tool type is a stylus.
+ static const int kToolTypeStylus = 2;
+
+ /// Value for `toolType` when the tool type is a mouse.
+ static const int kToolTypeMouse = 3;
+
+ /// Value for `toolType` when the tool type is an eraser.
+ static const int kToolTypeEraser = 4;
+
+ List _asList() => [id, toolType];
+
+ @override
+ String toString() {
+ return '${objectRuntimeType(this, 'OhosPointerProperties')}(id: $id, toolType: $toolType)';
+ }
+}
+
/// Position information for an Android pointer.
///
/// A Dart version of Android's [MotionEvent.PointerCoords](https://developer.android.com/reference/android/view/MotionEvent.PointerCoords).
@@ -408,6 +515,73 @@ class AndroidPointerCoords {
}
}
+class OhosPointerCoords {
+ /// Creates an OhosPointerCoords.
+ ///
+ /// All parameters must not be null.
+ const OhosPointerCoords({
+ required this.orientation,
+ required this.pressure,
+ required this.size,
+ required this.toolMajor,
+ required this.toolMinor,
+ required this.touchMajor,
+ required this.touchMinor,
+ required this.x,
+ required this.y,
+ }) : assert(orientation != null),
+ assert(pressure != null),
+ assert(size != null),
+ assert(toolMajor != null),
+ assert(toolMinor != null),
+ assert(touchMajor != null),
+ assert(touchMinor != null),
+ assert(x != null),
+ assert(y != null);
+
+ /// The orientation of the touch area and tool area in radians clockwise from vertical.
+ final double orientation;
+
+ /// A normalized value that describes the pressure applied to the device by a finger or other tool.
+ final double pressure;
+
+ /// A normalized value that describes the approximate size of the pointer touch area in relation to the maximum detectable size of the device.
+ final double size;
+
+ final double toolMajor;
+
+ final double toolMinor;
+
+ final double touchMajor;
+
+ final double touchMinor;
+
+ /// The X component of the pointer movement.
+ final double x;
+
+ /// The Y component of the pointer movement.
+ final double y;
+
+ List _asList() {
+ return [
+ orientation,
+ pressure,
+ size,
+ toolMajor,
+ toolMinor,
+ touchMajor,
+ touchMinor,
+ x,
+ y,
+ ];
+ }
+
+ @override
+ String toString() {
+ return '${objectRuntimeType(this, 'OhosPointerCoords')}(orientation: $orientation, pressure: $pressure, size: $size, toolMajor: $toolMajor, toolMinor: $toolMinor, touchMajor: $touchMajor, touchMinor: $touchMinor, x: $x, y: $y)';
+ }
+}
+
/// A Dart version of Android's [MotionEvent](https://developer.android.com/reference/android/view/MotionEvent).
///
/// This is used by [AndroidViewController] to describe pointer events that are forwarded to a platform view
@@ -532,6 +706,114 @@ class AndroidMotionEvent {
}
}
+class OhosMotionEvent {
+ /// Creates an OhosMotionEvent.
+ ///
+ /// All parameters must not be null.
+ OhosMotionEvent({
+ required this.downTime,
+ required this.eventTime,
+ required this.action,
+ required this.pointerCount,
+ required this.pointerProperties,
+ required this.pointerCoords,
+ required this.metaState,
+ required this.buttonState,
+ required this.xPrecision,
+ required this.yPrecision,
+ required this.deviceId,
+ required this.edgeFlags,
+ required this.source,
+ required this.flags,
+ required this.motionEventId,
+ }) : assert(downTime != null),
+ assert(eventTime != null),
+ assert(action != null),
+ assert(pointerCount != null),
+ assert(pointerProperties != null),
+ assert(pointerCoords != null),
+ assert(metaState != null),
+ assert(buttonState != null),
+ assert(xPrecision != null),
+ assert(yPrecision != null),
+ assert(deviceId != null),
+ assert(edgeFlags != null),
+ assert(source != null),
+ assert(flags != null),
+ assert(pointerProperties.length == pointerCount),
+ assert(pointerCoords.length == pointerCount);
+
+ /// The time (in ms) when the user originally pressed down to start a stream of position events,
+ /// relative to an arbitrary timeline.
+ final int downTime;
+
+ /// The time this event occurred, relative to an arbitrary timeline.
+ final int eventTime;
+
+ /// A value representing the kind of action being performed.
+ final int action;
+
+ /// The number of pointers that are part of this event.
+ /// This must be equivalent to the length of `pointerProperties` and `pointerCoords`.
+ final int pointerCount;
+
+ /// List of [OhosPointerProperties] for each pointer that is part of this event.
+ final List pointerProperties;
+
+ /// List of [OhosPointerCoords] for each pointer that is part of this event.
+ final List pointerCoords;
+
+ /// The state of any meta / modifier keys that were in effect when the event was generated.
+ final int metaState;
+
+ /// The state of all buttons that are pressed such as a mouse or stylus button.
+ final int buttonState;
+
+ /// The precision of the X coordinates being reported, in physical pixels.
+ final double xPrecision;
+
+ /// The precision of the Y coordinates being reported, in physical pixels.
+ final double yPrecision;
+
+ final int deviceId;
+
+ /// A bit field indicating which edges, if any, were touched by this MotionEvent.
+ final int edgeFlags;
+
+ /// The source of this event (e.g a touchpad or stylus).
+ final int source;
+
+ final int flags;
+
+ final int motionEventId;
+
+ List _asList(int viewId) {
+ return [
+ viewId,
+ downTime,
+ eventTime,
+ action,
+ pointerCount,
+ pointerProperties.map>((OhosPointerProperties p) => p._asList()).toList(),
+ pointerCoords.map>((OhosPointerCoords p) => p._asList()).toList(),
+ metaState,
+ buttonState,
+ xPrecision,
+ yPrecision,
+ deviceId,
+ edgeFlags,
+ source,
+ flags,
+ motionEventId,
+ ];
+ }
+
+ @override
+ String toString() {
+ return 'OhosPointerEvent(downTime: $downTime, eventTime: $eventTime, action: $action, pointerCount: $pointerCount, pointerProperties: $pointerProperties, pointerCoords: $pointerCoords, metaState: $metaState, buttonState: $buttonState, xPrecision: $xPrecision, yPrecision: $yPrecision, deviceId: $deviceId, edgeFlags: $edgeFlags, source: $source, flags: $flags, motionEventId: $motionEventId)';
+ }
+}
+
enum _AndroidViewState {
waitingForSize,
creating,
@@ -539,6 +821,13 @@ enum _AndroidViewState {
disposed,
}
+enum _OhosViewState {
+ waitingForSize,
+ creating,
+ created,
+ disposed,
+}
+
// Helper for converting PointerEvents into AndroidMotionEvents.
class _AndroidMotionEventConverter {
_AndroidMotionEventConverter();
@@ -1372,6 +1661,791 @@ class _HybridAndroidViewControllerInternals extends _AndroidViewControllerIntern
}
}
+class _OhosMotionEventConverter {
+ _OhosMotionEventConverter();
+
+ final Map pointerPositions =
+ {};
+ final Map pointerProperties =
+ {};
+ final Set usedOhosPointerIds = {};
+
+ PointTransformer get pointTransformer => _pointTransformer;
+ late PointTransformer _pointTransformer;
+ set pointTransformer(PointTransformer transformer) {
+ assert(transformer != null);
+ _pointTransformer = transformer;
+ }
+
+ int? downTimeMillis;
+
+ void handlePointerDownEvent(PointerDownEvent event) {
+ if (pointerProperties.isEmpty) {
+ downTimeMillis = event.timeStamp.inMilliseconds;
+ }
+ int ohosPointerId = 0;
+ while (usedOhosPointerIds.contains(ohosPointerId)) {
+ ohosPointerId++;
+ }
+ usedOhosPointerIds.add(ohosPointerId);
+ pointerProperties[event.pointer] = propertiesFor(event, ohosPointerId);
+ }
+
+ void updatePointerPositions(PointerEvent event) {
+ final Offset position = _pointTransformer(event.position);
+ pointerPositions[event.pointer] = OhosPointerCoords(
+ orientation: event.orientation,
+ pressure: event.pressure,
+ size: event.size,
+ toolMajor: event.radiusMajor,
+ toolMinor: event.radiusMinor,
+ touchMajor: event.radiusMajor,
+ touchMinor: event.radiusMinor,
+ x: position.dx,
+ y: position.dy,
+ );
+ }
+
+ void _remove(int pointer) {
+ pointerPositions.remove(pointer);
+ usedOhosPointerIds.remove(pointerProperties[pointer]!.id);
+ pointerProperties.remove(pointer);
+ if (pointerProperties.isEmpty) {
+ downTimeMillis = null;
+ }
+ }
+
+ void handlePointerUpEvent(PointerUpEvent event) {
+ _remove(event.pointer);
+ }
+
+ void handlePointerCancelEvent(PointerCancelEvent event) {
+ // The pointer cancel event is handled like pointer up. Normally,
+ // the difference is that pointer cancel doesn't perform any action,
+ // but in this case neither up or cancel perform any action.
+ _remove(event.pointer);
+ }
+
+ OhosMotionEvent? toOhosMotionEvent(PointerEvent event) {
+ final List pointers = pointerPositions.keys.toList();
+ final int pointerIdx = pointers.indexOf(event.pointer);
+ final int numPointers = pointers.length;
+
+ // This value must match the value in engine's FlutterView.java.
+ // This flag indicates whether the original Ohos pointer events were batched together.
+ const int kPointerDataFlagBatched = 1;
+
+ // Ohos MotionEvent objects can batch information on multiple pointers.
+ // Flutter breaks these such batched events into multiple PointerEvent objects.
+ // When there are multiple active pointers we accumulate the information for all pointers
+ // as we get PointerEvents, and only send it to the embedded Ohos view when
+ // we see the last pointer. This way we achieve the same batching as Ohos.
+ if (event.platformData == kPointerDataFlagBatched ||
+ (isSinglePointerAction(event) && pointerIdx < numPointers - 1)) {
+ return null;
+ }
+
+ final int action;
+ if (event is PointerDownEvent) {
+ action = numPointers == 1
+ ? OhosViewController.kActionDown
+ : OhosViewController.pointerAction(pointerIdx, OhosViewController.kActionPointerDown);
+ } else if (event is PointerUpEvent) {
+ action = numPointers == 1
+ ? OhosViewController.kActionUp
+ : OhosViewController.pointerAction(pointerIdx, OhosViewController.kActionPointerUp);
+ } else if (event is PointerMoveEvent) {
+ action = OhosViewController.kActionMove;
+ } else if (event is PointerCancelEvent) {
+ action = OhosViewController.kActionCancel;
+ } else {
+ return null;
+ }
+
+ return OhosMotionEvent(
+ downTime: downTimeMillis!,
+ eventTime: event.timeStamp.inMilliseconds,
+ action: action,
+ pointerCount: pointerPositions.length,
+ pointerProperties: pointers
+ .map((int i) => pointerProperties[i]!)
+ .toList(),
+ pointerCoords: pointers
+ .map((int i) => pointerPositions[i]!)
+ .toList(),
+ metaState: 0,
+ buttonState: 0,
+ xPrecision: 1.0,
+ yPrecision: 1.0,
+ deviceId: 0,
+ edgeFlags: 0,
+ source: 0,
+ flags: 0,
+ motionEventId: event.embedderId,
+ );
+ }
+
+ OhosPointerProperties propertiesFor(PointerEvent event, int pointerId) {
+ int toolType = OhosPointerProperties.kToolTypeUnknown;
+ switch (event.kind) {
+ case PointerDeviceKind.touch:
+ case PointerDeviceKind.trackpad:
+ toolType = OhosPointerProperties.kToolTypeFinger;
+ break;
+ case PointerDeviceKind.mouse:
+ toolType = OhosPointerProperties.kToolTypeMouse;
+ break;
+ case PointerDeviceKind.stylus:
+ toolType = OhosPointerProperties.kToolTypeStylus;
+ break;
+ case PointerDeviceKind.invertedStylus:
+ toolType = OhosPointerProperties.kToolTypeEraser;
+ break;
+ case PointerDeviceKind.unknown:
+ toolType = OhosPointerProperties.kToolTypeUnknown;
+ break;
+ }
+ return OhosPointerProperties(id: pointerId, toolType: toolType);
+ }
+
+ bool isSinglePointerAction(PointerEvent event) =>
+ event is! PointerDownEvent && event is! PointerUpEvent;
+}
+
+abstract class OhosViewController extends PlatformViewController {
+ OhosViewController._({
+ required this.viewId,
+ required String viewType,
+ required TextDirection layoutDirection,
+ dynamic creationParams,
+ MessageCodec? creationParamsCodec,
+ }) : assert(viewId != null),
+ assert(viewType != null),
+ assert(layoutDirection != null),
+ assert(creationParams == null || creationParamsCodec != null),
+ _viewType = viewType,
+ _layoutDirection = layoutDirection,
+ _creationParams = creationParams == null ? null : _CreationParams(creationParams, creationParamsCodec!);
+
+ /// Action code for when a primary pointer touched the screen.
+ ///
+ static const int kActionDown = 0;
+
+ /// Action code for when a primary pointer stopped touching the screen.
+ ///
+ static const int kActionUp = 1;
+
+ /// Action code for when the event only includes information about pointer movement.
+ ///
+ static const int kActionMove = 2;
+
+ /// Action code for when a motion event has been canceled.
+ ///
+ static const int kActionCancel = 3;
+
+ /// Action code for when a secondary pointer touched the screen.
+ ///
+ static const int kActionPointerDown = 5;
+
+ /// Action code for when a secondary pointer stopped touching the screen.
+ ///
+ static const int kActionPointerUp = 6;
+
+ static const int kOhosLayoutDirectionLtr = 0;
+
+ static const int kOhosLayoutDirectionRtl = 1;
+
+ /// The unique identifier of the Ohos view controlled by this controller.
+ @override
+ final int viewId;
+
+ final String _viewType;
+
+ // Helps convert PointerEvents to OhosMotionEvents.
+ final _OhosMotionEventConverter _motionEventConverter =
+ _OhosMotionEventConverter();
+
+ TextDirection _layoutDirection;
+
+ _OhosViewState _state = _OhosViewState.waitingForSize;
+
+ final _CreationParams? _creationParams;
+
+ final List _platformViewCreatedCallbacks =
+ [];
+
+ static int _getOhosDirection(TextDirection direction) {
+ assert(direction != null);
+ switch (direction) {
+ case TextDirection.ltr:
+ return kOhosLayoutDirectionLtr;
+ case TextDirection.rtl:
+ return kOhosLayoutDirectionRtl;
+ }
+ }
+
+ /// Creates a masked Ohos MotionEvent action value for an indexed pointer.
+ static int pointerAction(int pointerId, int action) {
+ return ((pointerId << 8) & 0xff00) | (action & 0xff);
+ }
+
+ /// Sends the message to dispose the platform view.
+ Future _sendDisposeMessage();
+
+ /// True if [_sendCreateMessage] can only be called with a non-null size.
+ bool get _createRequiresSize;
+
+ /// Sends the message to create the platform view with an initial [size].
+ ///
+ /// If [_createRequiresSize] is true, `size` is non-nullable, and the call
+ /// should instead be deferred until the size is available.
+ Future _sendCreateMessage({required covariant Size? size, Offset? position});
+
+ /// Sends the message to resize the platform view to [size].
+ Future _sendResizeMessage(Size size);
+
+ @override
+ bool get awaitingCreation => _state == _OhosViewState.waitingForSize;
+
+ @override
+ Future create({Size? size, Offset? position}) async {
+ assert(_state != _OhosViewState.disposed, 'trying to create a disposed Ohos view');
+ assert(_state == _OhosViewState.waitingForSize, 'Ohos view is already sized. View id: $viewId');
+
+ if (_createRequiresSize && size == null) {
+ // Wait for a setSize call.
+ return;
+ }
+
+ _state = _OhosViewState.creating;
+ await _sendCreateMessage(size: size, position: position);
+ _state = _OhosViewState.created;
+
+ for (final PlatformViewCreatedCallback callback in _platformViewCreatedCallbacks) {
+ callback(viewId);
+ }
+ }
+
+ /// Sizes the Ohos View.
+ ///
+ /// [size] is the view's new size in logical pixel, it must not be null and must
+ /// be bigger than zero.
+ ///
+ /// The first time a size is set triggers the creation of the Ohos view.
+ ///
+ /// Returns the buffer size in logical pixel that backs the texture where the platform
+ /// view pixels are written to.
+ ///
+ /// The buffer size may or may not be the same as [size].
+ ///
+ /// As a result, consumers are expected to clip the texture using [size], while using
+ /// the return value to size the texture.
+ Future setSize(Size size) async {
+ assert(_state != _OhosViewState.disposed, 'Ohos view is disposed. View id: $viewId');
+ if (_state == _OhosViewState.waitingForSize) {
+ // Either `create` hasn't been called, or it couldn't run due to missing
+ // size information, so create the view now.
+ await create(size: size);
+ return size;
+ } else {
+ return _sendResizeMessage(size);
+ }
+ }
+
+ /// Sets the offset of the platform view.
+ ///
+ /// [off] is the view's new offset in logical pixel.
+ ///
+ /// On Ohos, this allows the Ohos native view to draw the a11y highlights in the same
+ /// location on the screen as the platform view widget in the Flutter framework.
+ Future setOffset(Offset off);
+
+ /// Returns the texture entry id that the Ohos view is rendering into.
+ ///
+ /// Returns null if the Ohos view has not been successfully created, if it has been
+ /// disposed, or if the implementation does not use textures.
+ int? get textureId;
+
+ /// True if the view requires native view composition rather than using a
+ /// texture to render.
+ ///
+ /// This value may change during [create], but will not change after that
+ /// call's future has completed.
+ bool get requiresViewComposition => false;
+
+ /// for description of the parameters.
+ ///
+ /// See [OhosViewController.dispatchPointerEvent] for sending a
+ /// [PointerEvent].
+ Future sendMotionEvent(OhosMotionEvent event) async {
+ await SystemChannels.platform_views.invokeMethod(
+ 'touch',
+ event._asList(viewId),
+ );
+ }
+
+ /// Converts a given point from the global coordinate system in logical pixels
+ /// to the local coordinate system for this box.
+ ///
+ /// This is required to convert a [PointerEvent] to an [OhosMotionEvent].
+ /// It is typically provided by using [RenderBox.globalToLocal].
+ PointTransformer get pointTransformer => _motionEventConverter._pointTransformer;
+ set pointTransformer(PointTransformer transformer) {
+ assert(transformer != null);
+ _motionEventConverter._pointTransformer = transformer;
+ }
+
+ /// Whether the platform view has already been created.
+ bool get isCreated => _state == _OhosViewState.created;
+
+ /// Adds a callback that will get invoke after the platform view has been
+ /// created.
+ void addOnPlatformViewCreatedListener(PlatformViewCreatedCallback listener) {
+ assert(listener != null);
+ assert(_state != _OhosViewState.disposed);
+ _platformViewCreatedCallbacks.add(listener);
+ }
+
+ /// Removes a callback added with [addOnPlatformViewCreatedListener].
+ void removeOnPlatformViewCreatedListener(PlatformViewCreatedCallback listener) {
+ assert(listener != null);
+ assert(_state != _OhosViewState.disposed);
+ _platformViewCreatedCallbacks.remove(listener);
+ }
+
+ /// The created callbacks that are invoked after the platform view has been
+ /// created.
+ @visibleForTesting
+ List get createdCallbacks => _platformViewCreatedCallbacks;
+
+ /// Sets the layout direction for the Ohos view.
+ Future setLayoutDirection(TextDirection layoutDirection) async {
+ assert(
+ _state != _OhosViewState.disposed,
+ 'trying to set a layout direction for a disposed UIView. View id: $viewId',
+ );
+
+ if (layoutDirection == _layoutDirection) {
+ return;
+ }
+
+ assert(layoutDirection != null);
+ _layoutDirection = layoutDirection;
+
+ // If the view was not yet created we just update _layoutDirection and return, as the new
+ // direction will be used in _create.
+ if (_state == _OhosViewState.waitingForSize) {
+ return;
+ }
+
+ await SystemChannels.platform_views
+ .invokeMethod('setDirection', {
+ 'id': viewId,
+ 'direction': _getOhosDirection(layoutDirection),
+ });
+ }
+
+ /// to the view.
+ ///
+ /// This method can only be used if a [PointTransformer] is provided to
+ /// [OhosViewController.pointTransformer]. Otherwise, an [AssertionError]
+ /// is thrown. See [OhosViewController.sendMotionEvent] for sending a
+ /// `MotionEvent` without a [PointTransformer].
+ ///
+
+ /// for description of the parameters.
+ @override
+ Future dispatchPointerEvent(PointerEvent event) async {
+ if (event is PointerHoverEvent) {
+ return;
+ }
+
+ if (event is PointerDownEvent) {
+ _motionEventConverter.handlePointerDownEvent(event);
+ }
+
+ _motionEventConverter.updatePointerPositions(event);
+
+ final OhosMotionEvent? ohosEvent =
+ _motionEventConverter.toOhosMotionEvent(event);
+
+ if (event is PointerUpEvent) {
+ _motionEventConverter.handlePointerUpEvent(event);
+ } else if (event is PointerCancelEvent) {
+ _motionEventConverter.handlePointerCancelEvent(event);
+ }
+
+ if (ohosEvent != null) {
+ await sendMotionEvent(ohosEvent);
+ }
+ }
+
+ /// Clears the focus from the Ohos View if it is focused.
+ @override
+ Future clearFocus() {
+ if (_state != _OhosViewState.created) {
+ return Future.value();
+ }
+ return SystemChannels.platform_views.invokeMethod('clearFocus', viewId);
+ }
+
+ /// Disposes the Ohos view.
+ ///
+ /// The [OhosViewController] object is unusable after calling this.
+ /// The identifier of the platform view cannot be reused after the view is
+ /// disposed.
+ @override
+ Future dispose() async {
+ if (_state == _OhosViewState.creating || _state == _OhosViewState.created) {
+ await _sendDisposeMessage();
+ }
+ _platformViewCreatedCallbacks.clear();
+ _state = _OhosViewState.disposed;
+ PlatformViewsService._instance._focusCallbacks.remove(viewId);
+ }
+}
+
+class SurfaceOhosViewController extends OhosViewController {
+ SurfaceOhosViewController._({
+ required super.viewId,
+ required super.viewType,
+ required super.layoutDirection,
+ super.creationParams,
+ super.creationParamsCodec,
+ }) : super._();
+
+ // By default, assume the implementation will be texture-based.
+ _OhosViewControllerInternals _internals = _TextureOhosViewControllerInternals();
+
+ @override
+ bool get _createRequiresSize => true;
+
+ @override
+ Future _sendCreateMessage({required Size size, Offset? position}) async {
+ assert(!size.isEmpty, 'trying to create $TextureAndroidViewController without setting a valid size.');
+
+ final dynamic response = await _OhosViewControllerInternals.sendCreateMessage(
+ viewId: viewId,
+ viewType: _viewType,
+ hybrid: false,
+ hybridFallback: true,
+ layoutDirection: _layoutDirection,
+ creationParams: _creationParams,
+ size: size,
+ position: position,
+ );
+ if (response is int) {
+ (_internals as _TextureOhosViewControllerInternals).textureId = response;
+ } else {
+ // A null response indicates fallback to Hybrid Composition, so swap out
+ // the implementation.
+ _internals = _HybridOhosViewControllerInternals();
+ }
+ return true;
+ }
+
+ @override
+ int? get textureId {
+ return _internals.textureId;
+ }
+
+ @override
+ bool get requiresViewComposition {
+ return _internals.requiresViewComposition;
+ }
+
+ @override
+ Future _sendDisposeMessage() {
+ return _internals.sendDisposeMessage(viewId: viewId);
+ }
+
+ @override
+ Future _sendResizeMessage(Size size) {
+ return _internals.setSize(size, viewId: viewId, viewState: _state);
+ }
+
+ @override
+ Future setOffset(Offset off) {
+ return _internals.setOffset(off, viewId: viewId, viewState: _state);
+ }
+}
+
+class ExpensiveOhosViewController extends OhosViewController {
+ ExpensiveOhosViewController._({
+ required super.viewId,
+ required super.viewType,
+ required super.layoutDirection,
+ super.creationParams,
+ super.creationParamsCodec,
+ }) : super._();
+
+ final _OhosViewControllerInternals _internals = _HybridOhosViewControllerInternals();
+
+ @override
+ bool get _createRequiresSize => false;
+
+ @override
+ Future _sendCreateMessage({required Size? size, Offset? position}) async {
+ await _OhosViewControllerInternals.sendCreateMessage(
+ viewId: viewId,
+ viewType: _viewType,
+ hybrid: true,
+ layoutDirection: _layoutDirection,
+ creationParams: _creationParams,
+ position: position,
+ );
+ }
+
+ @override
+ int? get textureId {
+ return _internals.textureId;
+ }
+
+ @override
+ bool get requiresViewComposition {
+ return _internals.requiresViewComposition;
+ }
+
+ @override
+ Future _sendDisposeMessage() {
+ return _internals.sendDisposeMessage(viewId: viewId);
+ }
+
+ @override
+ Future _sendResizeMessage(Size size) {
+ return _internals.setSize(size, viewId: viewId, viewState: _state);
+ }
+
+ @override
+ Future setOffset(Offset off) {
+ return _internals.setOffset(off, viewId: viewId, viewState: _state);
+ }
+}
+
+class TextureOhosViewController extends OhosViewController {
+ TextureOhosViewController._({
+ required super.viewId,
+ required super.viewType,
+ required super.layoutDirection,
+ super.creationParams,
+ super.creationParamsCodec,
+ }) : super._();
+
+ final _TextureOhosViewControllerInternals _internals = _TextureOhosViewControllerInternals();
+
+ @override
+ bool get _createRequiresSize => true;
+
+ @override
+ Future _sendCreateMessage({required Size size, Offset? position}) async {
+ assert(!size.isEmpty, 'trying to create $TextureOhosViewController without setting a valid size.');
+
+ _internals.textureId = await _OhosViewControllerInternals.sendCreateMessage(
+ viewId: viewId,
+ viewType: _viewType,
+ hybrid: false,
+ layoutDirection: _layoutDirection,
+ creationParams: _creationParams,
+ size: size,
+ position: position,
+ ) as int;
+ }
+
+ @override
+ int? get textureId {
+ return _internals.textureId;
+ }
+
+ @override
+ bool get requiresViewComposition {
+ return _internals.requiresViewComposition;
+ }
+
+ @override
+ Future _sendDisposeMessage() {
+ return _internals.sendDisposeMessage(viewId: viewId);
+ }
+
+ @override
+ Future _sendResizeMessage(Size size) {
+ return _internals.setSize(size, viewId: viewId, viewState: _state);
+ }
+
+ @override
+ Future setOffset(Offset off) {
+ return _internals.setOffset(off, viewId: viewId, viewState: _state);
+ }
+}
+
+abstract class _OhosViewControllerInternals {
+ // Sends a create message with the given parameters, and returns the result
+ // if any.
+ //
+ // This uses a dynamic return because depending on the mode that is selected
+ // on the native side, the return type is different. Callers should cast
+ // depending on the possible return types for their arguments.
+ static Future sendCreateMessage({
+ required int viewId,
+ required String viewType,
+ required TextDirection layoutDirection,
+ required bool hybrid,
+ bool hybridFallback = false,
+ _CreationParams? creationParams,
+ Size? size,
+ Offset? position}) {
+ final Map args = {
+ 'id': viewId,
+ 'viewType': viewType,
+ 'direction': OhosViewController._getOhosDirection(layoutDirection),
+ if (hybrid == true) 'hybrid': hybrid,
+ if (size != null) 'width': size.width,
+ if (size != null) 'height': size.height,
+ if (hybridFallback == true) 'hybridFallback': hybridFallback,
+ if (position != null) 'left': position.dx,
+ if (position != null) 'top': position.dy,
+ };
+ if (creationParams != null) {
+ final ByteData paramsByteData = creationParams.codec.encodeMessage(creationParams.data)!;
+ args['params'] = Uint8List.view(
+ paramsByteData.buffer,
+ 0,
+ paramsByteData.lengthInBytes,
+ );
+ }
+ return SystemChannels.platform_views.invokeMethod('create', args);
+ }
+
+ int? get textureId;
+
+ bool get requiresViewComposition;
+
+ Future setSize(
+ Size size, {
+ required int viewId,
+ required _OhosViewState viewState,
+ });
+
+ Future setOffset(
+ Offset offset, {
+ required int viewId,
+ required _OhosViewState viewState,
+ });
+
+ Future sendDisposeMessage({required int viewId});
+}
+
+class _TextureOhosViewControllerInternals extends _OhosViewControllerInternals {
+ _TextureOhosViewControllerInternals();
+
+ /// The current offset of the platform view.
+ Offset _offset = Offset.zero;
+
+ @override
+ int? textureId;
+
+ @override
+ bool get requiresViewComposition => false;
+
+ @override
+ Future setSize(
+ Size size, {
+ required int viewId,
+ required _OhosViewState viewState,
+ }) async {
+ assert(viewState != _OhosViewState.waitingForSize, 'Ohos view must have an initial size. View id: $viewId');
+ assert(!size.isEmpty);
+
+ final Map