diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets index 11f1b234fb4acd7a734054ea0e5c4bc5f0cf9437..6a5b75e4bf3eac388ad091248bcbef49afa010ec 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets @@ -353,6 +353,22 @@ export default class FlutterNapi { } flutter.nativeGetSystemLanguages(this.nativeShellHolderId!, systemLanguages); } + + /** + * xcomponet绑定flutterEngine + * @param xcomponentId + */ + xComponentAttachFlutterEngine(xcomponentId: number) { + flutter.nativeXComponentAttachFlutterEngine(xcomponentId, this.nativeShellHolderId!); + } + + /** + * xcomponet解除绑定flutterEngine + * @param xcomponentId + */ + xComponentDetachFlutterEngine(xcomponentId: number) { + flutter.nativeXComponentDetachFlutterEngine(xcomponentId, this.nativeShellHolderId!); + } } export interface AccessibilityDelegate { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets index bc704b271787ea28059b6e29f9d676c9274f9146..7986cba7b7da9de3987acf22a2ad485f48dd10d8 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -37,35 +37,18 @@ import { DVModel, DVModelChildren, DVModelEvents, - DVModelParameters } from '../../view/DynamicView/dynamicView'; + DVModelParameters +} from '../../view/DynamicView/dynamicView'; import StringUtils from '../../util/StringUtils'; import List from '@ohos.util.List'; import ExclusiveAppComponent from './ExclusiveAppComponent'; +import { FlutterView } from '../../view/FlutterView'; import errorManager from '@ohos.app.ability.errorManager'; import appRecovery from '@ohos.app.ability.appRecovery'; const TAG = "FlutterAbility"; const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS'; -@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 function BuildXComponentStruct(buildParams: BuilderParams) { - XComponentStruct({dvModelParams: buildParams.params}); -} - /** * flutter ohos基础ability,请在让主ability继承自该类。 * 该类主要职责: @@ -78,6 +61,7 @@ export class FlutterAbility extends UIAbility implements Host { private mainWindow?: window.Window; private viewportMetrics = new ViewportMetrics(); private displayInfo?: display.Display; + private flutterView?: FlutterView | null private errorManagerId:number = 0; pagePath(): string { @@ -125,6 +109,7 @@ export class FlutterAbility extends UIAbility implements Host { onDestroy() { this.context.eventHub.off(EVENT_BACK_PRESS); if (this.stillAttachedForEvent("onDestroy")) { + this?.delegate?.onDestroyView(); this?.delegate?.onDestroy(); } errorManager.off('error', this.errorManagerId); @@ -190,12 +175,11 @@ export class FlutterAbility extends UIAbility implements Host { loadContent() { if (this.windowStage != null && this.stillAttachedForEvent("loadContent")) { Log.i(TAG, 'loadContent'); - 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); + if (!this.flutterView) { + if (this.delegate) { + this.flutterView = this.delegate?.onCreateView(); + } + } this.windowStage?.loadContent(this.pagePath(), (err, data) => { if (err.code) { @@ -353,7 +337,7 @@ export class FlutterAbility extends UIAbility implements Host { return true; } - shouldRestoreAndSaveState(): boolean{ + shouldRestoreAndSaveState(): boolean { if (this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { return this.launchWant.parameters![FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; } @@ -364,7 +348,7 @@ export class FlutterAbility extends UIAbility implements Host { return true; } - getPlugins(): List{ + getPlugins(): List { // Subclasses should override this function. return new List() } @@ -409,7 +393,7 @@ export class FlutterAbility extends UIAbility implements Host { } } - private onWindowPropertiesUpdated(){ + private onWindowPropertiesUpdated() { if (this.delegate == null || !this.delegate.isAttached) { return; } @@ -445,7 +429,7 @@ export class FlutterAbility extends UIAbility implements Host { } } - onConfigurationUpdated(config: Configuration){ + onConfigurationUpdated(config: Configuration) { Log.i(TAG, 'onConfigurationUpdated config:' + JSON.stringify(config)); this?.delegate?.flutterEngine?.getSettingsChannel()?.startMessage() .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) @@ -475,6 +459,10 @@ export class FlutterAbility extends UIAbility implements Host { getFlutterEngine(): FlutterEngine | null { return this.delegate?.flutterEngine || null; } + + getFlutterView(): FlutterView | null { + return this.flutterView ? this.flutterView : null; + } } export class ViewportMetrics { 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 a78d831f06c4284f9d5a4ae8a43c7c9cd53fd2b5..5eb7affeccd0724be95131ba5fde15ec0f7d0f60 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 @@ -37,6 +37,7 @@ import Settings from './Settings'; import FlutterNapi from '../engine/FlutterNapi'; import List from '@ohos.util.List'; import GeneratedPluginRegister from '../engine/plugins/util/GeneratedPluginRegister'; +import { FlutterView } from '../../view/FlutterView'; import { UIContext } from '@ohos.arkui.UIContext'; const TAG = "FlutterAbilityDelegate"; @@ -58,7 +59,8 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { private isFlutterEngineFromHost: boolean = false; private engineGroup?: FlutterEngineGroup; private settings?: Settings; - private isHost: boolean = false; + private isHost:boolean = false; + private flutterView?: FlutterView; constructor(host?: Host) { this.host = host; @@ -408,6 +410,30 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { } } + onCreateView(): FlutterView | null { + if (this.getFlutterNapi()) { + this.flutterView = new FlutterView(this.getFlutterNapi()!); + if (this.flutterEngine) { + this.flutterView?.attachToFlutterEngine(this.flutterEngine!) + }else{ + throw new Error('this.flutterEngine() is null!'); + } + return this.flutterView; + } else { + return null; + } + } + + /** + * Invoke this from {@code FlutterAbility#onDestroy()}. + * + * */ + onDestroyView() { + Log.i(TAG, "onDestroyView()"); + this.ensureAlive(); + this.flutterView?.detachFromFlutterEngine() + } + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { Log.i(TAG, "onSaveInstanceState. Giving framework and plugins an opportunity to save state."); this.ensureAlive(); diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index cf38a74159eb41c2ca4b6ede7f9e04e0cc66bf5a..8927c1a3584757e40b7d06a2f474f7ff95060aec 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -12,7 +12,80 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import util from '@ohos.util'; +import FlutterEngine from '../embedding/engine/FlutterEngine'; +import FlutterNapi from '../embedding/engine/FlutterNapi'; +import { RootDvModeManager } from '../plugin/platform/RootDvModelManager'; +import { BuilderParams, DVModel, DVModelChildren, DVModelEvents, DVModelParameters } from './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 +function BuildXComponentStruct(buildParams: BuilderParams) { + XComponentStruct({ dvModelParams: buildParams.params }); +} export class FlutterView { + private xcomponentId: number + private flutterEngine?: FlutterEngine | null + private flutterNapi: FlutterNapi + private isAttach: boolean + + constructor(flutterNapi: FlutterNapi) { + this.flutterNapi = flutterNapi + this.isAttach = false + this.xcomponentId = Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER + 1)); + } + + public getXComponentId(): number { + return this.xcomponentId; + } + + public getAttachedFlutterEngine(): FlutterEngine | null { + return this.flutterEngine ? this.flutterEngine : null; + } + + public attachToFlutterEngine(flutterEngine: FlutterEngine) { + this.flutterEngine = flutterEngine; + + // 1.给XComponent赋值id + let params: DVModelParameters = new DVModelParameters(); + (params as Record)["xComponentId"] = this.xcomponentId.toString() + let xComponentModel: DVModel = + new DVModel("xComponent", params, new DVModelEvents(), new DVModelChildren(), BuildXComponentStruct); + RootDvModeManager.addDvModel(xComponentModel); + + //2.xcomponent绑定engine + // 将shellHolder传递到C++侧,用于将Xcomponent和FlutterEngine绑定 + this.flutterNapi.xComponentAttachFlutterEngine(this.xcomponentId); + this.isAttach = true; + } + + public isAttachedToFlutterEngine(): boolean { + return this.isAttach; + } + public detachFromFlutterEngine() { + this.flutterNapi.xComponentDetachFlutterEngine(this.xcomponentId); + this.flutterEngine = null + this.isAttach = false + } } \ No newline at end of file diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index 7f88815b7b7ed605a21148ed09d36c686ad3ec04..bad3e98f765e273b3b27af89a632fdad6cc807c4 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -102,6 +102,14 @@ static napi_value Init(napi_env env, napi_value exports) { "nativeGetSystemLanguages", flutter::PlatformViewOHOSNapi::nativeGetSystemLanguages), + DECLARE_NAPI_FUNCTION( + "nativeXComponentAttachFlutterEngine", + flutter::PlatformViewOHOSNapi::nativeXComponentAttachFlutterEngine), + + DECLARE_NAPI_FUNCTION( + "nativeXComponentDetachFlutterEngine", + flutter::PlatformViewOHOSNapi::nativeXComponentDetachFlutterEngine), + }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); bool ret = flutter::XComponentAdapter::GetInstance()->Export(env, exports); diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 3da5999832a2295bb2342a6f3b9831a20847faa3..e4ea8ffc41593b3dc9af1ae0500f423826d694d8 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -25,6 +25,7 @@ #include "flutter/shell/platform/ohos/ohos_main.h" #include "flutter/shell/platform/ohos/ohos_shell_holder.h" #include "flutter/shell/platform/ohos/surface/ohos_native_window.h" +#include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" #include "unicode/uchar.h" #define OHOS_SHELL_HOLDER (reinterpret_cast(shell_holder)) @@ -1418,6 +1419,86 @@ napi_value PlatformViewOHOSNapi::nativeGetSystemLanguages( return nullptr; } +/** + * @brief xcomponent与flutter引擎绑定 + * @note + * @param nativeShellHolderId: number + * @param xcomponentId: number + * @return void + */ +napi_value PlatformViewOHOSNapi::nativeXComponentAttachFlutterEngine( + napi_env env, + napi_callback_info info){ + napi_status ret; + size_t argc = 2; + napi_value args[2] = {nullptr}; + int64_t xcomponent_id; + int64_t shell_holder; + ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine napi_get_cb_info error:" + << ret; + return nullptr; + } + ret = napi_get_value_int64(env, args[0], &xcomponent_id); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine xcomponent_id napi_get_value_int64 error"; + return nullptr; + } + ret = napi_get_value_int64(env, args[1], &shell_holder); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine shell_holder napi_get_value_int64 error"; + return nullptr; + } + std::string xcomponent_id_str = std::to_string(xcomponent_id); + std::string shell_holder_str = std::to_string(shell_holder); + + LOGD("nativeXComponentAttachFlutterEngine xcomponent_id: %{public}ld , shell_holder: %{public}ld ", + xcomponent_id, shell_holder); + + XComponentAdapter::GetInstance()->AttachFlutterEngine(xcomponent_id_str, + shell_holder_str); + return nullptr; +} +/** + * @brief xcomponent解除flutter引擎绑定 + * @note + * @param nativeShellHolderId: number + * @param xcomponentId: number + * @return napi_value + */ +napi_value PlatformViewOHOSNapi::nativeXComponentDetachFlutterEngine( + napi_env env, + napi_callback_info info){ + napi_status ret; + size_t argc = 2; + napi_value args[2] = {nullptr}; + int64_t xcomponent_id; + int64_t shell_holder; + ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine napi_get_cb_info error:" + << ret; + return nullptr; + } + ret = napi_get_value_int64(env, args[0], &xcomponent_id); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine xcomponent_id napi_get_value_int64 error"; + return nullptr; + } + ret = napi_get_value_int64(env, args[1], &shell_holder); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeXComponentAttachFlutterEngine shell_holder napi_get_value_int64 error"; + return nullptr; + } + std::string xcomponent_id_str = std::to_string(xcomponent_id); + + LOGD("nativeXComponentDetachFlutterEngine xcomponent_id: %{public}ld", + xcomponent_id); + XComponentAdapter::GetInstance()->DetachFlutterEngine(xcomponent_id_str); + return nullptr; +} + int64_t PlatformViewOHOSNapi::GetShellHolder() { return PlatformViewOHOSNapi::shell_holder_value; } diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index d32a6fe996af7bfc8c75556cda66321e12f13f51..2bf7d6eaaf3304676a980379b0d52fa474a99474 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -142,6 +142,12 @@ class PlatformViewOHOSNapi { static napi_value nativeGetSystemLanguages( napi_env env, napi_callback_info info); // 应用下发系统语言设置 + static napi_value nativeXComponentAttachFlutterEngine( + napi_env env, + napi_callback_info info); + static napi_value nativeXComponentDetachFlutterEngine( + napi_env env, + napi_callback_info info); // Surface相关,XComponent调用 static void SurfaceCreated(int64_t shell_holder, void* window); diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.cpp b/shell/platform/ohos/ohos_xcomponent_adapter.cpp index 29e820b67d997495737199f589cdd3e2e73ef40c..51891a471d3dccc4a347394ef29375a0862c7cc2 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.cpp +++ b/shell/platform/ohos/ohos_xcomponent_adapter.cpp @@ -70,10 +70,36 @@ void XComponentAdapter::SetNativeXComponent( std::string& id, OH_NativeXComponent* nativeXComponent) { auto iter = xcomponetMap_.find(id); - if(iter == xcomponetMap_.end()) { - XComponentBase* xcomponet = new XComponentBase(id, nativeXComponent); + if (iter == xcomponetMap_.end()) { + XComponentBase* xcomponet = new XComponentBase(id); xcomponetMap_[id] = xcomponet; } + + iter = xcomponetMap_.find(id); + if (iter != xcomponetMap_.end()) { + iter->second->SetNativeXComponent(nativeXComponent); + } +} + +void XComponentAdapter::AttachFlutterEngine(std::string& id, + std::string& shellholderId) { + auto iter = xcomponetMap_.find(id); + if (iter == xcomponetMap_.end()) { + XComponentBase* xcomponet = new XComponentBase(id); + xcomponetMap_[id] = xcomponet; + } + + auto findIter = xcomponetMap_.find(id); + if (findIter != xcomponetMap_.end()) { + findIter->second->AttachFlutterEngine(shellholderId); + } +} + +void XComponentAdapter::DetachFlutterEngine(std::string& id) { + auto iter = xcomponetMap_.find(id); + if (iter != xcomponetMap_.end()) { + iter->second->DetachFlutterEngine(); + } } #include @@ -213,22 +239,38 @@ void XComponentBase::BindXComponentCallback() { callback_.DispatchTouchEvent = DispatchTouchEventCB; } -XComponentBase::XComponentBase(std::string id,OH_NativeXComponent* xcomponet) { - nativeXComponent_ = xcomponet; +XComponentBase::XComponentBase(std::string id){ + id_ = id; + isAttached_ = false; +} + +XComponentBase::~XComponentBase() {} + +void XComponentBase::AttachFlutterEngine(std::string shellholderId) { + LOGD( + "XComponentManger::AttachFlutterEngine xcomponentId:%{public}s, " + "shellholderId:%{public}s", + id_.c_str(), shellholderId.c_str()); + shellholderId_ = shellholderId; + isAttached_ = true; +} + +void XComponentBase::DetachFlutterEngine() { + shellholderId_ = ""; + isAttached_ = false; + nativeXComponent_ = nullptr; +} + +void XComponentBase::SetNativeXComponent(OH_NativeXComponent* nativeXComponent){ + nativeXComponent_ = nativeXComponent; if (nativeXComponent_ != nullptr) { - id_ = id; BindXComponentCallback(); OH_NativeXComponent_RegisterCallback(nativeXComponent_, &callback_); } } -XComponentBase::~XComponentBase() -{ - -} - -void XComponentBase::OnSurfaceCreated(OH_NativeXComponent* component, void* window) -{ +void XComponentBase::OnSurfaceCreated(OH_NativeXComponent* component, + void* window) { LOGD( "XComponentManger::OnSurfaceCreated window = %{public}p component = " "%{public}p", @@ -248,7 +290,11 @@ void XComponentBase::OnSurfaceCreated(OH_NativeXComponent* component, void* wind if (ret) { LOGD("SetNativeWindowOpt failed:%{public}d", ret); } - PlatformViewOHOSNapi::SurfaceCreated(std::stoll(id_), window); + if (isAttached_) { + PlatformViewOHOSNapi::SurfaceCreated(std::stoll(shellholderId_), window); + } else { + LOGE("OnSurfaceCreated XComponentBase is not attached"); + } } void XComponentBase::OnSurfaceChanged(OH_NativeXComponent* component, void* window) @@ -260,22 +306,38 @@ void XComponentBase::OnSurfaceChanged(OH_NativeXComponent* component, void* wind LOGD("XComponent Current width:%{public}d,height:%{public}d", static_cast(width_), static_cast(height_)); } - PlatformViewOHOSNapi::SurfaceChanged(std::stoll(id_), width_, height_); + if (isAttached_) { + PlatformViewOHOSNapi::SurfaceChanged(std::stoll(shellholderId_), width_, + height_); + } else { + LOGE("OnSurfaceChanged XComponentBase is not attached"); + } } -void XComponentBase::OnSurfaceDestroyed(OH_NativeXComponent* component, void* window) -{ +void XComponentBase::OnSurfaceDestroyed(OH_NativeXComponent* component, + void* window) { LOGD("XComponentManger::OnSurfaceDestroyed"); - PlatformViewOHOSNapi::SurfaceDestroyed(std::stoll(id_)); + if (isAttached_) { + PlatformViewOHOSNapi::SurfaceDestroyed(std::stoll(shellholderId_)); + } else { + LOGE("OnSurfaceCreated OnSurfaceDestroyed is not attached"); + } } -void XComponentBase::OnDispatchTouchEvent(OH_NativeXComponent* component, void* window) -{ +void XComponentBase::OnDispatchTouchEvent(OH_NativeXComponent* component, + void* window) { LOGD("XComponentManger::DispatchTouchEvent"); int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_); if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { - ohosTouchProcessor_.HandleTouchEvent(std::stoll(id_), component, &touchEvent_); + if (isAttached_) { + ohosTouchProcessor_.HandleTouchEvent(std::stoll(shellholderId_), + component, &touchEvent_); + } else { + LOGE( + "XComponentManger::DispatchTouchEvent XComponentBase is not " + "attached"); + } } } diff --git a/shell/platform/ohos/ohos_xcomponent_adapter.h b/shell/platform/ohos/ohos_xcomponent_adapter.h index 210483e3927e24853c2c4a405eaf690fec87a119..a888a7a1f48a546d52a7d7ac555c8d46f5331b2a 100644 --- a/shell/platform/ohos/ohos_xcomponent_adapter.h +++ b/shell/platform/ohos/ohos_xcomponent_adapter.h @@ -29,9 +29,13 @@ private: void BindXComponentCallback(); public: - XComponentBase(std::string id_, OH_NativeXComponent* xcomponet); + XComponentBase(std::string id); ~XComponentBase(); + void AttachFlutterEngine(std::string shellholderId); + void DetachFlutterEngine(); + void SetNativeXComponent(OH_NativeXComponent* nativeXComponent); + // Callback, called by ACE XComponent void OnSurfaceCreated(OH_NativeXComponent* component, void* window); void OnSurfaceChanged(OH_NativeXComponent* component, void* window); @@ -41,6 +45,8 @@ public: OH_NativeXComponent_TouchEvent touchEvent_; OH_NativeXComponent_Callback callback_; std::string id_; + std::string shellholderId_; + bool isAttached_; OH_NativeXComponent* nativeXComponent_; uint64_t width_; uint64_t height_; @@ -56,6 +62,8 @@ class XComponentAdapter { bool Export(napi_env env, napi_value exports); void SetNativeXComponent(std::string& id, OH_NativeXComponent* nativeXComponent); + void AttachFlutterEngine(std::string& id, std::string& shellholderId); + void DetachFlutterEngine(std::string& id); public: std::map xcomponetMap_;