diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/component/XComponentStruct.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/component/XComponentStruct.ets new file mode 100644 index 0000000000000000000000000000000000000000..e9d66ef987b8c8f070bb6279a2035fc06fc8c054 --- /dev/null +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/component/XComponentStruct.ets @@ -0,0 +1,35 @@ +/* +* 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 { BuilderParams, DVModelParameters } from '../view/DynamicView/dynamicView'; + +@Component +struct XComponentStruct { + private context:ESObject; + dvModelParams: DVModelParameters = new DVModelParameters(); + + build() { + XComponent({ id: (this.dvModelParams as Record)["xComponentId"], type: 'texture', libraryname: 'flutter'}) + .onLoad((context) => { + this.context = context; + }) + .onDestroy(() => { + }) + } +} + +@Builder export function BuildXComponentStruct(buildParams: BuilderParams) { + XComponentStruct({dvModelParams: buildParams.params}); +} \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets index 31a454eb7e77a084b7a9c83688cecd477721b359..d7bfe2805ebf83c89cf2b98fa913c0852b1ca5c6 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets @@ -54,9 +54,13 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { private isFlutterEngineFromHost: boolean = false; private engineGroup?: FlutterEngineGroup; private settings?: Settings; + private isHost:boolean = false; - constructor(host: Host) { + constructor(host?: Host) { this.host = host; + if (this.host) { + this.isHost = true; + } } /** @@ -99,9 +103,10 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { let initialRoute = this.host?.getInitialRoute(); if (initialRoute == null && this.host != null) { initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); - if (initialRoute == null) { - initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; - } + + } + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; } const libraryUri = this.host?.getDartEntrypointLibraryUri(); Log.d(TAG, "Executing Dart entrypoint: " + this.host?.getDartEntrypointFunctionName() + ", library uri: " + libraryUri == null ? "\"\"" : libraryUri + ", and sending initial route: " + initialRoute); @@ -197,9 +202,10 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { "No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterAbility."); let group = this.engineGroup; - if (group == null && this.context != null && this.host != null) { + if (group == null && this.context != null) { group = new FlutterEngineGroup(); - await group.checkLoader(this.context, this.host.getFlutterShellArgs().toArray() ?? []); + const flutterShellArgs = this.host? this.host.getFlutterShellArgs(): new FlutterShellArgs(); + await group.checkLoader(this.context, flutterShellArgs.toArray() ?? []); this.engineGroup = group; } if (this.context) { @@ -222,13 +228,13 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { let initialRoute = this.host?.getInitialRoute(); if (initialRoute == null && this.host != null) { initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); - if (initialRoute == null) { - initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; - } + } + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; } return options .setDartEntrypoint(dartEntrypoint) - .setInitialRoute(initialRoute ?? '') + .setInitialRoute(initialRoute) .setDartEntrypointArgs(this.host?.getDartEntrypointArgs() ?? []); } @@ -314,6 +320,9 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { */ shouldDispatchAppLifecycleState(): boolean { + if (!this.isHost) { + return this.isAttached; + } if (this.host == null) { return false; } @@ -321,7 +330,7 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { } ensureAlive() { - if (this.host == null) { + if (this.isHost && this.host == null) { throw new Error("Cannot execute method on a destroyed FlutterAbilityDelegate."); } } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterComopnentDelegate.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterComopnentDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..7cec8a4a5de637bcc285c5449415e093a7d3f551 --- /dev/null +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterComopnentDelegate.ets @@ -0,0 +1,153 @@ +/* +* 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 { FlutterAbilityDelegate } from './FlutterAbilityDelegate'; +import window from '@ohos.window'; +import { ViewportMetrics } from './FlutterAbility'; +import { + BuilderParams, + DVModel, + DVModelChildren, + DVModelEvents, + DVModelParameters +} from '../../view/DynamicView/dynamicView'; +import display from '@ohos.display'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import { BuildXComponentStruct } from '../../component/XComponentStruct'; + +export class FlutterComponentDelegate { + private context: common.UIAbilityContext + + private delegate?: FlutterAbilityDelegate | null; + + private mainWindow?: window.Window; + + private viewportMetrics = new ViewportMetrics(); + + constructor(context: common.UIAbilityContext) { + this.context = context; + this.delegate = new FlutterAbilityDelegate(); + } + + async init(): Promise { + let displayInfo = display.getDefaultDisplaySync(); + this.viewportMetrics.devicePixelRatio = displayInfo?.densityPixels; + await this?.delegate?.onAttach(this.context); + this?.delegate?.platformPlugin?.setUIAbilityContext(this.context); + this?.delegate?.sendSettings(); + let params: DVModelParameters = new DVModelParameters(); + (params as Record)["xComponentId"] = + this.delegate?.getFlutterNapi()?.nativeShellHolderId?.toString(); + let xComponentModel: DVModel = + new DVModel("xComponent", params, new DVModelEvents(), new DVModelChildren(), BuildXComponentStruct); + RootDvModeManager.addDvModel(xComponentModel); + this.mainWindow = await window.getLastWindow(this.context); + this.mainWindow?.on( + 'windowSizeChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow?.on( + 'avoidAreaChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow?.on( + 'keyboardHeightChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + this.onWindowPropertiesUpdated(); + this?.delegate?.onWindowStageCreate(); + this?.delegate?.onWindowFocusChanged(true); + this?.delegate?.onForeground(); + } + + private onWindowPropertiesUpdated() { + if (this.delegate == null || !this.delegate.isAttached) { + return; + } + let systemAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + let gestureAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); + let keyboardAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + const properties = this.mainWindow?.getWindowProperties(); + if (properties!.windowRect.width < this.viewportMetrics.physicalWidth) { + this.viewportMetrics.physicalWidth = properties!.windowRect.width; + } + if (properties!.windowRect.height < this.viewportMetrics.physicalHeight) { + this.viewportMetrics.physicalHeight = properties!.windowRect.height; + } + + this.viewportMetrics.physicalViewPaddingTop = systemAvoidArea!.topRect.height + this.viewportMetrics.physicalViewPaddingLeft = systemAvoidArea!.leftRect.width + this.viewportMetrics.physicalViewPaddingBottom = systemAvoidArea!.bottomRect.height + this.viewportMetrics.physicalViewPaddingRight = systemAvoidArea!.rightRect.width + + this.viewportMetrics.physicalViewInsetTop = keyboardAvoidArea!.topRect.height + this.viewportMetrics.physicalViewInsetLeft = keyboardAvoidArea!.leftRect.width + this.viewportMetrics.physicalViewInsetBottom = keyboardAvoidArea!.bottomRect.height + this.viewportMetrics.physicalViewInsetRight = keyboardAvoidArea!.rightRect.width + + this.viewportMetrics.systemGestureInsetTop = gestureAvoidArea!.topRect.height + this.viewportMetrics.systemGestureInsetLeft = gestureAvoidArea!.leftRect.width + this.viewportMetrics.systemGestureInsetBottom = gestureAvoidArea!.bottomRect.height + this.viewportMetrics.systemGestureInsetRight = gestureAvoidArea!.rightRect.width + + this.updateViewportMetrics() + } + + private updateViewportMetrics() { + this?.delegate?.getFlutterNapi()?.setViewportMetrics( + this.viewportMetrics.devicePixelRatio, + this.viewportMetrics.physicalWidth, + this.viewportMetrics.physicalHeight, + this.viewportMetrics.physicalViewPaddingTop, + this.viewportMetrics.physicalViewPaddingRight, + this.viewportMetrics.physicalViewPaddingBottom, + this.viewportMetrics.physicalViewPaddingLeft, + this.viewportMetrics.physicalViewInsetTop, + this.viewportMetrics.physicalViewInsetRight, + this.viewportMetrics.physicalViewInsetBottom, + this.viewportMetrics.physicalViewInsetLeft, + this.viewportMetrics.systemGestureInsetTop, + this.viewportMetrics.systemGestureInsetRight, + this.viewportMetrics.systemGestureInsetBottom, + this.viewportMetrics.systemGestureInsetLeft, + this.viewportMetrics.physicalTouchSlop, + new Array(0), + new Array(0), + new Array(0) + ) + } + + addPlugin(plugin: FlutterPlugin): void { + this.delegate?.addPlugin(plugin) + } + + release(): void { + if (this?.delegate != null) { + this?.delegate?.onDestroy(); + this?.delegate?.release(); + this.delegate = null; + } + } + + updateView(width: number, height: number): void { + this.viewportMetrics.physicalWidth = width; + this.viewportMetrics.physicalHeight = height; + this.updateViewportMetrics(); + } +} \ No newline at end of file diff --git a/shell/platform/ohos/ohos_touch_processor.cpp b/shell/platform/ohos/ohos_touch_processor.cpp index 202f07ddb92fbb714cf6725cb8cd6e4aa1d41e12..47f8a838ff3524bbeff1342f75543a5ddda65f29 100644 --- a/shell/platform/ohos/ohos_touch_processor.cpp +++ b/shell/platform/ohos/ohos_touch_processor.cpp @@ -79,8 +79,8 @@ void OhosTouchProcessor::HandleTouchEvent( touchEvent->touchPoints[index].timeStamp / MSEC_PER_SECOND; pointerData.change = getPointerChangeForAction(touchEvent->touchPoints[index].type); - pointerData.physical_y = touchEvent->touchPoints[index].screenY; - pointerData.physical_x = touchEvent->touchPoints[index].screenX; + pointerData.physical_y = touchEvent->touchPoints[index].y; + pointerData.physical_x = touchEvent->touchPoints[index].x; // Delta will be generated in pointer_data_packet_converter.cc. pointerData.physical_delta_x = 0.0; pointerData.physical_delta_y = 0.0; @@ -114,21 +114,6 @@ void OhosTouchProcessor::HandleTouchEvent( pointerData.size = touchEvent->touchPoints[index].size; pointerData.scale = 1.0; pointerData.rotation = 0.0; - LOGD( - "Touch Info:dots[%{public}d] id %{public}d x = %{public}f, y = " - "%{public}f type %{public}d", - static_cast(index), touchEvent->touchPoints[index].id, - touchEvent->touchPoints[index].x, touchEvent->touchPoints[index].y, - touchEvent->touchPoints[index].type); - LOGD("Touch Info : screenx = %{public}f, screeny = %{public}f", - touchEvent->touchPoints[index].screenX, - touchEvent->touchPoints[index].screenY); - LOGD( - "vtimeStamp = %{public}ld, isPressed = %{public}d toolType = " - "%{public}d", - touchEvent->touchPoints[index].timeStamp, - touchEvent->touchPoints[index].isPressed, toolType); - packet->SetPointerData(index, pointerData); } auto ohos_shell_holder = reinterpret_cast(shell_holderID);