diff --git a/fml/BUILD.gn b/fml/BUILD.gn index b8b6c6c5ceaf5c84d22622c15fb963cc2102483f..03d286857c2d7308c91dca9f445e59e484069b50 100644 --- a/fml/BUILD.gn +++ b/fml/BUILD.gn @@ -200,6 +200,7 @@ source_set("fml") { #"platform/ohos/message_loop_ohos_test.h", "platform/ohos/napi_util.h", "platform/ohos/napi_util.cc", + "platform/ohos/ohos_trace_event.cc", ] libs += [ "hilog_ndk.z" ] libs += [ "ace_napi.z" ] diff --git a/fml/platform/ohos/ohos_trace_event.cc b/fml/platform/ohos/ohos_trace_event.cc new file mode 100644 index 0000000000000000000000000000000000000000..18f90a07e649dbf7b7b48197f3cc7e4df8f664a3 --- /dev/null +++ b/fml/platform/ohos/ohos_trace_event.cc @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2024 Huawei Device 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. + */ + +#include "flutter/fml/trace_event.h" + +#include + +#if defined(FML_OS_OHOS) +namespace fml { +namespace tracing { + +static constexpr char OHOS_COLON[] = ":"; +static constexpr char OHOS_SCOPE[] = "::"; +static constexpr char OHOS_WHITESPACE[] = " "; +static constexpr char OHOS_FILTER_NAME_SCENE[] = "SceneDisplayLag"; +static constexpr char OHOS_FILTER_NAME_POINTER[] = "PointerEvent"; + +void OHOSTraceTimelineEvent(TraceArg category_group, + TraceArg name, + TraceIDArg id, + Dart_Timeline_Event_Type type, + intptr_t argument_count, + const char** argument_names, + const char** argument_values) { + if (type != Dart_Timeline_Event_Begin && type != Dart_Timeline_Event_Async_Begin && + type != Dart_Timeline_Event_Async_End && type != Dart_Timeline_Event_Flow_Begin && + type != Dart_Timeline_Event_Flow_End) { + return; + } + + if (type != Dart_Timeline_Event_Begin && strcmp(name, OHOS_FILTER_NAME_POINTER) == 0) { + // Trace 'PointerEvent' is not work in the scenario of extenal texture + return; + } + + int realNumber = argument_count; + if (type != Dart_Timeline_Event_Begin && strcmp(name, OHOS_FILTER_NAME_SCENE) == 0) { + // Trace 'SceneDisplayLag' have inconsistent parameters. It's not good to watch. + realNumber = 0; + } + + std::string TraceName(category_group); + TraceName.append(OHOS_SCOPE); + TraceName.append(name); + + if (argument_names != nullptr && argument_values != nullptr) { + for (int i = 0; i < realNumber; i++) { + std::string TraceParam(OHOS_WHITESPACE); + TraceName += TraceParam + argument_names[i] + OHOS_COLON + argument_values[i]; + } + } + + switch(type) { + case Dart_Timeline_Event_Begin: + OH_HiTrace_StartTrace(TraceName.c_str()); + break; + case Dart_Timeline_Event_Async_Begin: + case Dart_Timeline_Event_Flow_Begin: + OH_HiTrace_StartAsyncTrace(TraceName.c_str(), id); + break; + case Dart_Timeline_Event_Async_End: + case Dart_Timeline_Event_Flow_End: + OH_HiTrace_FinishAsyncTrace(TraceName.c_str(), id); + break; + default: + break; + } + return; +} + +void OHOSTraceEventEnd(void) { + OH_HiTrace_FinishTrace(); +} + +} // namespace tracing +} // namespace fml +#endif // FML_OS_OHOS diff --git a/fml/trace_event.cc b/fml/trace_event.cc index 7ec9adbab3118a41f1c4a2b12d9fd638012c2719..af92a4447727bf3a07b6f7036bdb95c43fa747ab 100644 --- a/fml/trace_event.cc +++ b/fml/trace_event.cc @@ -94,6 +94,10 @@ void TraceTimelineEvent(TraceArg category_group, const_cast(c_names.data()), // argument_names c_values.data() // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, 0, type, argument_count, const_cast(c_names.data()), + c_values.data()); +#endif } void TraceTimelineEvent(TraceArg category_group, @@ -121,6 +125,9 @@ void TraceEvent0(TraceArg category_group, TraceArg name) { nullptr, // argument_names nullptr // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, 0, Dart_Timeline_Event_Begin, 0, nullptr, nullptr); +#endif } void TraceEvent1(TraceArg category_group, @@ -137,6 +144,9 @@ void TraceEvent1(TraceArg category_group, arg_names, // argument_names arg_values // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, 0, Dart_Timeline_Event_Begin, 1, arg_names, arg_values); +#endif } void TraceEvent2(TraceArg category_group, @@ -155,6 +165,9 @@ void TraceEvent2(TraceArg category_group, arg_names, // argument_names arg_values // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, 0, Dart_Timeline_Event_Begin, 2, arg_names, arg_values); +#endif } void TraceEventEnd(TraceArg name) { @@ -166,6 +179,9 @@ void TraceEventEnd(TraceArg name) { nullptr, // argument_names nullptr // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceEventEnd(); +#endif } void TraceEventAsyncBegin0(TraceArg category_group, @@ -179,6 +195,9 @@ void TraceEventAsyncBegin0(TraceArg category_group, nullptr, // argument_names nullptr // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, id, Dart_Timeline_Event_Async_Begin, 0, nullptr, nullptr); +#endif } void TraceEventAsyncEnd0(TraceArg category_group, @@ -192,6 +211,9 @@ void TraceEventAsyncEnd0(TraceArg category_group, nullptr, // argument_names nullptr // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, id, Dart_Timeline_Event_Async_End, 0, nullptr, nullptr); +#endif } void TraceEventAsyncBegin1(TraceArg category_group, @@ -209,6 +231,9 @@ void TraceEventAsyncBegin1(TraceArg category_group, arg_names, // argument_names arg_values // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, id, Dart_Timeline_Event_Async_Begin, 1, arg_names, arg_values); +#endif } void TraceEventAsyncEnd1(TraceArg category_group, @@ -226,6 +251,9 @@ void TraceEventAsyncEnd1(TraceArg category_group, arg_names, // argument_names arg_values // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, id, Dart_Timeline_Event_Async_End, 1, arg_names, arg_values); +#endif } void TraceEventInstant0(TraceArg category_group, TraceArg name) { @@ -284,6 +312,9 @@ void TraceEventFlowBegin0(TraceArg category_group, nullptr, // argument_names nullptr // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, id, Dart_Timeline_Event_Flow_Begin, 0, nullptr, nullptr); +#endif } void TraceEventFlowStep0(TraceArg category_group, @@ -308,6 +339,9 @@ void TraceEventFlowEnd0(TraceArg category_group, TraceArg name, TraceIDArg id) { nullptr, // argument_names nullptr // argument_values ); +#if defined(FML_OS_OHOS) + OHOSTraceTimelineEvent(category_group, name, id, Dart_Timeline_Event_Flow_End, 0, nullptr, nullptr); +#endif } #else // FLUTTER_TIMELINE_ENABLED diff --git a/fml/trace_event.h b/fml/trace_event.h index ce7bcf359509c91041b99a7225ac9c490356fd0c..2c24208ff3615c81396d672f0ab6c9cd04b99fc3 100644 --- a/fml/trace_event.h +++ b/fml/trace_event.h @@ -73,17 +73,18 @@ public: #define TRACE_DURATION_LINE(line, fmt, args...) OHFlutterTrace TRACE_NAME(__OH_trace_, line)(fmt, args) #define TRACE_DURATION(fmt, args...) TRACE_DURATION_LINE(__LINE__, fmt, args) -#define TRACE_FMT "%s:%s " -#define OH_TRACE_DURATION(a, b) TRACE_DURATION(TRACE_FMT, a, b) - -#define OH_TRACE_ASYNC_BEGIN(category, name, id) OH_HiTrace_StartAsyncTrace(category#name, id) -#define OH_TRACE_ASYNC_END(category, name, id) OH_HiTrace_FinishAsyncTrace(category#name, id) +#define TRACE_FMT0 "%s::%s" +#define TRACE_FMT1 "%s::%s %s:%s" +#define TRACE_FMT2 "%s::%s %s:%s %s:%s" +#define OH_TRACE_DURATION0(a, b) TRACE_DURATION(TRACE_FMT0, a, b) +#define OH_TRACE_DURATION1(a, b, c, d) TRACE_DURATION(TRACE_FMT1, a, b, c, d) +#define OH_TRACE_DURATION2(a, b, c, d, e, f) TRACE_DURATION(TRACE_FMT2, a, b, c, d, e, f) #else -#define OH_TRACE_DURATION(a, b) -#define OH_TRACE_ASYNC_BEGIN(category, name, id) -#define OH_TRACE_ASYNC_END(category, name, id) +#define OH_TRACE_DURATION0(a, b) +#define OH_TRACE_DURATION1(a, b, c, d) +#define OH_TRACE_DURATION2(a, b, c, d, e, f) #endif // defined(FML_OS_OHOS) @@ -135,69 +136,60 @@ public: // Instead, either use different `name` or `arg1` parameter names. #define FML_TRACE_EVENT(category_group, name, ...) \ ::fml::tracing::TraceEvent((category_group), (name), __VA_ARGS__); \ - __FML__AUTO_TRACE_END(name); \ - OH_TRACE_DURATION((category_group), (name)) + __FML__AUTO_TRACE_END(name) #define TRACE_EVENT0(category_group, name) \ ::fml::tracing::TraceEvent0(category_group, name); \ - __FML__AUTO_TRACE_END(name); \ - OH_TRACE_DURATION((category_group), (name)) + __FML__AUTO_TRACE_END(name) #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \ ::fml::tracing::TraceEvent1(category_group, name, arg1_name, arg1_val); \ - __FML__AUTO_TRACE_END(name); \ - OH_TRACE_DURATION((category_group), (name)) + __FML__AUTO_TRACE_END(name) #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \ arg2_val) \ ::fml::tracing::TraceEvent2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val); \ - __FML__AUTO_TRACE_END(name); \ - OH_TRACE_DURATION((category_group), (name)) + __FML__AUTO_TRACE_END(name) #define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \ - ::fml::tracing::TraceEventAsyncBegin0(category_group, name, id); \ - OH_TRACE_ASYNC_BEGIN(category_group, name, (id)) + ::fml::tracing::TraceEventAsyncBegin0(category_group, name, id) #define TRACE_EVENT_ASYNC_END0(category_group, name, id) \ - ::fml::tracing::TraceEventAsyncEnd0(category_group, name, id); \ - OH_TRACE_ASYNC_END(category_group, name, (id)) + ::fml::tracing::TraceEventAsyncEnd0(category_group, name, id) #define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \ arg1_val) \ ::fml::tracing::TraceEventAsyncBegin1(category_group, name, id, arg1_name, \ - arg1_val); \ - OH_TRACE_ASYNC_BEGIN(category_group, name, (id)) + arg1_val) #define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \ ::fml::tracing::TraceEventAsyncEnd1(category_group, name, id, arg1_name, \ - arg1_val); \ - OH_TRACE_ASYNC_END(category_group, name, (id)) + arg1_val) #define TRACE_EVENT_INSTANT0(category_group, name) \ ::fml::tracing::TraceEventInstant0(category_group, name); \ - OH_TRACE_DURATION((category_group), (name)) + OH_TRACE_DURATION0((category_group), (name)) #define TRACE_EVENT_INSTANT1(category_group, name, arg1_name, arg1_val) \ ::fml::tracing::TraceEventInstant1(category_group, name, arg1_name, arg1_val); \ - OH_TRACE_DURATION((category_group), (name)) + OH_TRACE_DURATION1((category_group), (name), (arg1_name), (arg1_val)) #define TRACE_EVENT_INSTANT2(category_group, name, arg1_name, arg1_val, \ arg2_name, arg2_val) \ ::fml::tracing::TraceEventInstant2(category_group, name, arg1_name, \ arg1_val, arg2_name, arg2_val); \ - OH_TRACE_DURATION((category_group), (name)) + OH_TRACE_DURATION2((category_group), (name), (arg1_name), (arg1_val), \ + (arg2_name), (arg2_val)) #define TRACE_FLOW_BEGIN(category, name, id) \ - ::fml::tracing::TraceEventFlowBegin0(category, name, id); \ - OH_TRACE_ASYNC_BEGIN(category, name, (id)) + ::fml::tracing::TraceEventFlowBegin0(category, name, id) #define TRACE_FLOW_STEP(category, name, id) \ ::fml::tracing::TraceEventFlowStep0(category, name, id) #define TRACE_FLOW_END(category, name, id) \ - ::fml::tracing::TraceEventFlowEnd0(category, name, id); \ - OH_TRACE_ASYNC_END(category, name, (id)) + ::fml::tracing::TraceEventFlowEnd0(category, name, id) #endif // TRACE_EVENT_HIDE_MACROS #endif // !defined(OS_FUCHSIA) @@ -243,6 +235,18 @@ void TraceTimelineEvent(TraceArg category_group, const std::vector& names, const std::vector& values); +#if defined(FML_OS_OHOS) +void OHOSTraceTimelineEvent(TraceArg category_group, + TraceArg name, + TraceIDArg id, + Dart_Timeline_Event_Type type, + intptr_t argument_count, + const char** argument_names, + const char** argument_values); + +void OHOSTraceEventEnd(void); +#endif // FML_OS_OHOS + inline std::string TraceToString(const char* string) { return std::string{string}; } diff --git a/lib/ui/window/platform_message_response_dart.cc b/lib/ui/window/platform_message_response_dart.cc index 66c07c31c36ed2c7063542484b9a34dee1665213..3f43e20451884d21a0f6539102b804083e00f88c 100644 --- a/lib/ui/window/platform_message_response_dart.cc +++ b/lib/ui/window/platform_message_response_dart.cc @@ -39,8 +39,9 @@ void PostCompletion(Callback&& callback, ui_task_runner->PostTask(fml::MakeCopyable( [callback = std::move(callback), platform_message_id, result = std::move(result), channel = channel]() mutable { - TRACE_EVENT_ASYNC_END0("flutter", "PlatformChannel ScheduleResult", - platform_message_id); + // Pair with TRACE_EVENT_ASYNC_BEGIN1 + TRACE_EVENT_ASYNC_END1("flutter", "PlatformChannel ScheduleResult", + platform_message_id, "channel", channel.c_str()); std::shared_ptr dart_state = callback.dart_state().lock(); if (!dart_state) { diff --git a/shell/platform/ohos/flutter_embedding/flutter/oh-package.json5 b/shell/platform/ohos/flutter_embedding/flutter/oh-package.json5 index 8c53bcea950310b995e8dbde1f7cce6675f36377..39bbaa64c01def1568782d0af4659f2391b78fad 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/oh-package.json5 +++ b/shell/platform/ohos/flutter_embedding/flutter/oh-package.json5 @@ -16,8 +16,8 @@ { "license": "Apache-2.0", "author": "", - "name": "flutter", - "description": "Please describe the basic information.", + "name": "@ohos/flutter_ohos", + "description": "The embedder of flutter in ohos.", "main": "index.ets", "version": "1.0.0", "dependencies": {}, diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets index 45a76fdda8da51301ac9dab19cd5cb37c46f391d..53a5eabeca7ef8c0b205a413100d8693733f1c4a 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets @@ -17,6 +17,7 @@ import common from '@ohos.app.ability.common'; import resourceManager from '@ohos.resourceManager'; import image from '@ohos.multimedia.image'; import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; +import { FlutterCallbackInformation } from '../../../ets/view/FlutterCallbackInformation'; export const getContext: (a: number) => napiContext; @@ -132,3 +133,5 @@ export const nativeEncodeUtf8: (str: string) => Uint8Array; export const nativeDecodeUtf8: (array: Uint8Array) => string; export const nativeSetTextureBufferSize: (nativeShellHolderId: number, textureId: number, width: number, height: number) => void; + +export const nativeLookupCallbackInformation: (callback: FlutterCallbackInformation, handler: number) => number; \ No newline at end of file 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 75f4a58b453dcc38d1af218a83b334dcd2efe144..78f1a520e7ec6efbc792f1164c8933dafc439d6d 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 @@ -101,8 +101,8 @@ export default class FlutterNapi { runBundleAndSnapshotFromLibrary( bundlePath: string, - entrypointFunctionName: string, - pathToEntrypointFunction: string, + entrypointFunctionName: string | undefined, + pathToEntrypointFunction: string | undefined, assetManager: resourceManager.ResourceManager, entrypointArgs: Array) { if (!FlutterNapi.hasInit) { @@ -138,6 +138,11 @@ export default class FlutterNapi { } static nativeLookupCallbackInformation(handle: number): FlutterCallbackInformation | null { + let callbackInformation = new FlutterCallbackInformation(); + let ret : number = flutter.nativeLookupCallbackInformation(callbackInformation, handle); + if (ret == 0) { + return callbackInformation; + } return null; } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets index 8afbc9222396e8c7c3437818b36f7c05469fb9cd..caf39c49165ef42fcd90c20e7c823f1a7eda01e9 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets @@ -321,7 +321,8 @@ class PlatformMethodCallback implements MethodCallHandler { case "SystemChrome.setApplicationSwitcherDescription": Log.d(PlatformMethodCallback.TAG, "setApplicationSwitcherDescription: " + JSON.stringify(args)); try { - this.platform.platformMessageHandler.setApplicationSwitcherDescription(args); + let description: AppSwitcherDescription = this.decodeAppSwitcherDescription(args); + this.platform.platformMessageHandler.setApplicationSwitcherDescription(description); result.success(null); } catch (err) { Log.e(PlatformMethodCallback.TAG, "setApplicationSwitcherDescription err:" + JSON.stringify(err)); @@ -398,6 +399,12 @@ class PlatformMethodCallback implements MethodCallHandler { } } + private decodeAppSwitcherDescription(encodedDescription: Map): AppSwitcherDescription { + let color: number = encodedDescription.get('color') as number; + let label: string = encodedDescription.get('label') as string; + return new AppSwitcherDescription(color, label); + } + private decodeSystemUiOverlays(encodedSystemUiOverlay: string[]): SystemUiOverlay[] { let overlays: SystemUiOverlay[] = []; for(let i = 0; i < encodedSystemUiOverlay.length; i++) { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets index 8b7a13ff5ac742b6bb52de6df043412f80e58443..124eb6488d1a9d8062a3d9133f34564e798cd57d 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterEntry.ets @@ -129,6 +129,7 @@ export default class FlutterEntry implements Host { onBackPress() { Log.d(TAG, "FlutterEntry onBackPress==="); this?.delegate?.flutterEngine?.getNavigationChannel()?.popRoute(); + this?.delegate?.flutterEngine?.getTextInputChannel()?.textInputMethodHandler?.hide(); } shouldDispatchAppLifecycleState(): boolean { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets index 8bf6fcbbbfa2df00f8ef67780d370682cb69f1a3..aba17a326c8c3d8bcb9c19ccedb35dfec4477ad5 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -27,6 +27,7 @@ import { window } from '@kit.ArkUI'; import FlutterManager from '../../embedding/ohos/FlutterManager'; import { IntentionCode } from '@ohos.multimodalInput.intentionCode'; import {KeyCode} from '@kit.InputKit'; +import { BusinessError } from '@kit.BasicServicesKit'; /// 临时规避缺少newline对应枚举问题 const NEWLINE_KEY_TYPE: number = 8; @@ -84,7 +85,8 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { private mRestartInputPending: boolean = false; private plugin: EditingStateWatcher | Any; private imcFlag: boolean = false; - private showType: keyboardType = keyboardType.ENTRY + private inputTypeNone: string = 'NONE' + private firstShow: boolean = true; constructor(plugin: TextInputPlugin | Any) { this.textConfig = { @@ -97,11 +99,15 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { this.mEditable = new ListenableEditingState(null, 0); this.inputMethodController = inputMethod.getController(); this.inputTarget = new InputTarget(Type.NO_TARGET, 0); - this.listenShowKeyboardHeight(); } + /// 通过判断是否是TextInputType.none来决定是否弹出键盘 show(): void { - this.showTextInput(); + if (this.canShowTextInput()) { + this.showTextInput(); + } else { + this.hide(); + } } hide(): void { @@ -142,79 +148,48 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } private async showTextInput(): Promise { - /// 暂时规避方案 - /// NONE是打开软键盘,正常输入模式 - /// ENTRY是未弹出软键盘时的输入模式 - /// TRANSFER负责切换同一个页面内的TextField时重置键盘 - /// DONE是解决点击Entry时submitted回调使用弹窗而无法正常收起软键盘 - switch (this.showType) { - case keyboardType.NONE: - break; - case keyboardType.ENTRY: - this.showKeyboard(); - break; - case keyboardType.TRANSFER: - this.showKeyboard(); - break; - case keyboardType.DONE: - this.hideTextInput(); - break; - default: - break; + if (!this.firstShow) { + return } - } - - async showKeyboard() { - /// 添加软键盘弹出收起监听方法 - this.listenShowKeyboardHeight(); + this.listenShowKeyboard() await this.attach(true); - if (this.imcFlag != true) { + if (!this.imcFlag) { this.listenKeyBoardEvent(); } this.inputMethodController.showTextInput().then(() => { + this.firstShow = false Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in showing softKeyboard"); }).catch((err: Any) => { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to show softKeyboard:" + JSON.stringify(err)); }); - this.showType = keyboardType.NONE; - } - - listenShowKeyboardHeight() { - window.getLastWindow(getContext(this)).then(currentWindow => { - try { - currentWindow.on('keyboardHeightChange', (data) => { - console.info('Succeeded in enabling the listener for keyboard height changes. Data: ' + JSON.stringify(data)); - if (data == 0) { - this.showType = keyboardType.ENTRY - } else { - this.showType = keyboardType.NONE - } - }); - } catch (exception) { - console.error(`Failed to enable the listener for keyboard height changes. Cause code: ${exception.code}, message: ${exception.message}`); - } - }) - } - - /// 软键盘收起时关闭监听方法 - listenHideKeyboardHeight() { - window.getLastWindow(getContext(this)).then(currentWindow => { - try { - currentWindow.off('keyboardHeightChange'); - } catch (exception) { - console.error(`Failed to enable the listener for keyboard height changes. Cause code: ${exception.code}, message: ${exception.message}`); - } - }) } private async hideTextInput(): Promise { this.inputMethodController.hideTextInput().then(() => { + this.firstShow = true Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in hide softKeyboard"); }).catch((err: Any) => { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to hide softKeyboard:" + JSON.stringify(err)); }) - this.showType = keyboardType.ENTRY - this.listenHideKeyboardHeight() + this.listenNoShowKeyboard() + } + + /// 通过监听规避区域内,是否有软键盘区域来进行监听。该方法在回到桌面和锁屏依然可以正常监听 + listenShowKeyboard() { + let windowStage = FlutterManager.getInstance() + .getWindowStage(FlutterManager.getInstance().getUIAbility(getContext(this))); + windowStage.getMainWindow((err: BusinessError, currentWindow ) => { + currentWindow.on('avoidAreaChange', this.avoidAreaChangeCallback) + }); + } + + /// 取消监听规避区域的软键盘范围 + listenNoShowKeyboard() { + let windowStage = FlutterManager.getInstance() + .getWindowStage(FlutterManager.getInstance().getUIAbility(getContext(this))); + windowStage.getMainWindow((err: BusinessError, currentWindow ) => { + currentWindow.off('avoidAreaChange', this.avoidAreaChangeCallback) + }); } async attach(showKeyboard: boolean): Promise { @@ -260,21 +235,19 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { this.mRestartInputPending = true; this.mEditable.addEditingStateListener(this.plugin); + this.firstShow = true } canShowTextInput(): boolean { if (this.configuration == null || this.configuration.inputType == null) { return true; } - return this.configuration.inputType.type != TextInputType.NONE; + return this.configuration.inputType.type != this.inputTypeNone; } listenKeyBoardEvent(): void { try { - this.inputMethodController.on('insertText', (text) => { - Log.d(TextInputMethodHandlerImpl.TAG, "insertText: " + text); - this.mEditable.handleInsertTextEvent(text); - }); + this.inputMethodController.on('insertText', this.insertTextCallback); } catch (err) { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe insertText:" + JSON.stringify(err)); this.cancelListenKeyBoardEvent(); @@ -282,15 +255,7 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } try { - this.inputMethodController.on('deleteLeft', (length) => { - /// 暂时规避方案 - /// OS机制与Android不一致,需要去监听软键盘事件才能发送KeyEvent事件 - if (this.mEditable.getStringCache() == "") { - this.sendKeyboardEvent(KeyType.Down, KeyCode.KEYCODE_DEL) - this.sendKeyboardEvent(KeyType.Up, KeyCode.KEYCODE_DEL) - } - this.mEditable.handleDeleteEvent(false, length); - }) + this.inputMethodController.on('deleteLeft', this.deleteLeftCallback) } catch (err) { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteLeft:" + JSON.stringify(err)); this.cancelListenKeyBoardEvent(); @@ -298,9 +263,7 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } try { - this.inputMethodController.on('deleteRight', (length) => { - this.mEditable.handleDeleteEvent(true, length); - }) + this.inputMethodController.on('deleteRight', this.deleteRightCallback) } catch (err) { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteRight:" + JSON.stringify(err)); this.cancelListenKeyBoardEvent(); @@ -308,15 +271,7 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } try { - this.inputMethodController.on('sendFunctionKey', (functionKey) => { - /// 临时规避缺少newline对应枚举类型问题 - if (functionKey.enterKeyType == NEWLINE_KEY_TYPE) { - this.mEditable.handleNewlineEvent(); - } else { - this.showType = keyboardType.DONE - } - this.mEditable.handleFunctionKey(functionKey); - }) + this.inputMethodController.on('sendFunctionKey', this.sendFunctionKeyCallback) } catch (err) { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendFunctionKey:" + JSON.stringify(err)); this.cancelListenKeyBoardEvent(); @@ -324,16 +279,7 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } try { - this.inputMethodController.on('sendKeyboardStatus', (state) => { - if (state == inputMethod.KeyboardStatus.HIDE) { - this.plugin.textInputChannel.onConnectionClosed(this.inputTarget.id); - if (this.showType != keyboardType.DONE) { - this.showType = keyboardType.TRANSFER - } - this.hideTextInput() - this.cancelListenKeyBoardEvent() - } - }) + this.inputMethodController.on('sendKeyboardStatus', this.sendKeyboardStatusCallback) } catch (err) { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendKeyboardStatus:" + JSON.stringify(err)); this.cancelListenKeyBoardEvent(); @@ -341,9 +287,7 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { } try { - this.inputMethodController.on('selectByRange', (range: inputMethod.Range) => { - this.mEditable.handleSelectByRange(range); - }) + this.inputMethodController.on('selectByRange', this.selectByRangeCallback) } catch (err) { Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe selectByRange:" + JSON.stringify(err)); this.cancelListenKeyBoardEvent(); @@ -372,13 +316,64 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { }) } + private avoidAreaChangeCallback = (data: window.AvoidAreaOptions) => { + console.info('Succeeded in enabling the listener for keyboard height changes. Data: ' + JSON.stringify(data)); + if (data.type !== window.AvoidAreaType.TYPE_KEYBOARD) { + return; + } + if (data.area.bottomRect.height == 0) { + this.firstShow = true + } else { + this.firstShow = false + } + } + + private insertTextCallback = (text: string) => { + Log.d(TextInputMethodHandlerImpl.TAG, "insertText: " + text); + this.mEditable.handleInsertTextEvent(text); + } + + private deleteLeftCallback = (length: number) => { + /// 暂时规避方案 + /// OS机制与Android不一致,需要去监听软键盘事件才能发送KeyEvent事件 + if (this.mEditable.getStringCache() == "") { + this.sendKeyboardEvent(KeyType.Down, KeyCode.KEYCODE_DEL) + this.sendKeyboardEvent(KeyType.Up, KeyCode.KEYCODE_DEL) + } + this.mEditable.handleDeleteEvent(false, length); + } + + private deleteRightCallback = (length: number) => { + this.mEditable.handleDeleteEvent(true, length); + } + + private sendFunctionKeyCallback = (functionKey: inputMethod.FunctionKey) => { + /// 临时规避缺少newline对应枚举类型问题 + if (functionKey.enterKeyType == NEWLINE_KEY_TYPE) { + this.mEditable.handleNewlineEvent(); + } + this.mEditable.handleFunctionKey(functionKey); + } + + private sendKeyboardStatusCallback = (state: inputMethod.KeyboardStatus) => { + if (state == inputMethod.KeyboardStatus.HIDE) { + this.plugin.textInputChannel.onConnectionClosed(this.inputTarget.id); + this.hideTextInput() + this.cancelListenKeyBoardEvent() + } + } + + private selectByRangeCallback = (range: inputMethod.Range) => { + this.mEditable.handleSelectByRange(range); + } + cancelListenKeyBoardEvent(): void { - this.inputMethodController.off('insertText'); - this.inputMethodController.off('deleteLeft'); - this.inputMethodController.off('deleteRight'); - this.inputMethodController.off('sendFunctionKey'); - this.inputMethodController.off('sendKeyboardStatus'); - this.inputMethodController.off('selectByRange'); + this.inputMethodController.off('insertText', this.insertTextCallback); + this.inputMethodController.off('deleteLeft', this.deleteLeftCallback); + this.inputMethodController.off('deleteRight', this.deleteRightCallback); + this.inputMethodController.off('sendFunctionKey', this.sendFunctionKeyCallback); + this.inputMethodController.off('sendKeyboardStatus', this.sendKeyboardStatusCallback); + this.inputMethodController.off('selectByRange', this.selectByRangeCallback); this.imcFlag = false; } @@ -389,9 +384,6 @@ class TextInputMethodHandlerImpl implements TextInputMethodHandler { this.mEditable.removeEditingStateListener(this.plugin); this.configuration = null; this.inputTarget = new InputTarget(Type.NO_TARGET, 0); - if (this.showType != keyboardType.DONE) { - this.showType = keyboardType.TRANSFER - } this.resetAttach(); } } @@ -406,13 +398,6 @@ enum Type { PHYSICAL_DISPLAY_PLATFORM_VIEW, } -enum keyboardType { - NONE, - ENTRY, - TRANSFER, - DONE -} - export class InputTarget { type: Type; id: number; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterCallbackInformation.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterCallbackInformation.ets index 26202727fac9b327d8a4a024667ef30ea067a6e8..7f9111e95f95d9784422a7695dd0db712690763e 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterCallbackInformation.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterCallbackInformation.ets @@ -16,9 +16,9 @@ import FlutterNapi from '../embedding/engine/FlutterNapi'; export class FlutterCallbackInformation { - callbackName: string; - callbackClassName: string; - callbackLibraryPath: string; + callbackName?: string; + callbackClassName?: string; + callbackLibraryPath?: string; /** * Get callback information for a given handle. @@ -31,7 +31,13 @@ export class FlutterCallbackInformation { return FlutterNapi.nativeLookupCallbackInformation(handle); } - constructor(callbackName: string, callbackClassName: string, callbackLibraryPath: string) { + constructor(callbackName?: string, callbackClassName?: string, callbackLibraryPath?: string) { + this.callbackName = callbackName; + this.callbackClassName = callbackClassName; + this.callbackLibraryPath = callbackLibraryPath; + } + + init(callbackName: string, callbackClassName: string, callbackLibraryPath: string) { this.callbackName = callbackName; this.callbackClassName = callbackClassName; this.callbackLibraryPath = callbackLibraryPath; 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 03bdbc5b0845e3347894977acf72f17f61b2a3ef..59038f9f33d24d3a39d5a2a1329f996e68bc3151 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 @@ -46,6 +46,46 @@ export class ViewportMetrics { systemGestureInsetBottom: number = 0; systemGestureInsetLeft: number = 0; physicalTouchSlop: number = -1; + + clone(): ViewportMetrics { + const copy = new ViewportMetrics(); + copy.devicePixelRatio = this.devicePixelRatio; + copy.physicalWidth = this.physicalWidth; + copy.physicalHeight = this.physicalHeight; + copy.physicalViewPaddingTop = this.physicalViewPaddingTop; + copy.physicalViewPaddingRight = this.physicalViewPaddingRight; + copy.physicalViewPaddingBottom = this.physicalViewPaddingBottom; + copy.physicalViewPaddingLeft = this.physicalViewPaddingLeft; + copy.physicalViewInsetTop = this.physicalViewInsetTop; + copy.physicalViewInsetRight = this.physicalViewInsetRight; + copy.physicalViewInsetBottom = this.physicalViewInsetBottom; + copy.physicalViewInsetLeft = this.physicalViewInsetLeft; + copy.systemGestureInsetTop = this.systemGestureInsetTop; + copy.systemGestureInsetRight = this.systemGestureInsetRight; + copy.systemGestureInsetBottom = this.systemGestureInsetBottom; + copy.systemGestureInsetLeft = this.systemGestureInsetLeft; + copy.physicalTouchSlop = this.physicalTouchSlop; + return copy; + } + + isEqual(other: ViewportMetrics): boolean { + return this.devicePixelRatio === other.devicePixelRatio && + this.physicalWidth === other.physicalWidth && + this.physicalHeight === other.physicalHeight && + this.physicalViewPaddingTop === other.physicalViewPaddingTop && + this.physicalViewPaddingRight === other.physicalViewPaddingRight && + this.physicalViewPaddingBottom === other.physicalViewPaddingBottom && + this.physicalViewPaddingLeft === other.physicalViewPaddingLeft && + this.physicalViewInsetTop === other.physicalViewInsetTop && + this.physicalViewInsetRight === other.physicalViewInsetRight && + this.physicalViewInsetBottom === other.physicalViewInsetBottom && + this.physicalViewInsetLeft === other.physicalViewInsetLeft && + this.systemGestureInsetTop === other.systemGestureInsetTop && + this.systemGestureInsetRight === other.systemGestureInsetRight && + this.systemGestureInsetBottom === other.systemGestureInsetBottom && + this.systemGestureInsetLeft === other.systemGestureInsetLeft && + this.physicalTouchSlop === other.physicalTouchSlop; + } } export class PlatformViewParas { @@ -91,6 +131,11 @@ export class FlutterView { private checkFullScreen: boolean = true; private checkKeyboard: boolean = true; private checkGesture: boolean = true; + private systemAvoidArea: window.AvoidArea; + private navigationAvoidArea: window.AvoidArea; + private gestureAvoidArea: window.AvoidArea; + private keyboardAvoidArea: window.AvoidArea; + constructor(viewId: string, context: Context) { this.id = viewId @@ -106,6 +151,10 @@ export class FlutterView { this.mainWindow?.on('windowSizeChange', this.windowSizeChangeCallback); this.mainWindow?.on('avoidAreaChange', this.avoidAreaChangeCallback); this.mainWindow?.on('windowStatusChange', this.windowStatusChangeCallback); + this.systemAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + this.navigationAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + this.gestureAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); + this.keyboardAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); } private windowSizeChangeCallback = (data: window.Size) => { @@ -118,6 +167,15 @@ export class FlutterView { private avoidAreaChangeCallback = (data: window.AvoidAreaOptions) => { Log.i(TAG, "avoidAreaChangeCallback, type=" + data.type); if (this.isAttachedToFlutterEngine()) { + if (data.type == window.AvoidAreaType.TYPE_SYSTEM) { //0 + this.systemAvoidArea = data.area; + } else if (data.type == window.AvoidAreaType.TYPE_SYSTEM_GESTURE) { //2 + this.gestureAvoidArea = data.area; + } else if (data.type == window.AvoidAreaType.TYPE_KEYBOARD) { //3 + this.keyboardAvoidArea = data.area; + } else if (data.type == window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) { //4 + this.navigationAvoidArea = data.area; + } this.onAreaChange(null); } } @@ -202,6 +260,18 @@ export class FlutterView { this.flutterEngine?.getFlutterNapi()?.updateRefreshRate(this.displayInfo!.refreshRate) flutterEngine.getPlatformViewsController()?.attachToView(this); this.updateViewportMetrics() + + let newArea: Area | null = { + width: px2vp(this.displayInfo!.width), + height: px2vp(this.displayInfo!.height), + position: { x: 0, y: 0 }, + globalPosition: { x: 0, y: 0 } + }; + if (this.viewportMetrics.physicalWidth != 0 || this.viewportMetrics.physicalHeight != 0) { + newArea = null; + } + this.onAreaChange(newArea, true); + let windowId = this.mainWindow?.getWindowProperties()?.id ?? 0 this.mouseCursorPlugin = new MouseCursorPlugin(windowId, this.flutterEngine?.getMouseCursorChannel()!); this.settings = new Settings(this.flutterEngine.getSettingsChannel()!); @@ -257,9 +327,8 @@ export class FlutterView { } } - onAreaChange(newArea: Area | null) { - let systemAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); - let navigationAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); + onAreaChange(newArea: Area | null, setFullScreen: boolean = false) { + const originalMetrics = this.viewportMetrics.clone(); if (newArea != null) { this.viewportMetrics.physicalWidth = vp2px(newArea.width as number); @@ -267,21 +336,23 @@ export class FlutterView { } // 根据是否全屏显示,设置标题栏高度(若全屏,则及时规避) - if (this.checkFullScreen && FlutterManager.getInstance().getFullScreenListener().useFullScreen()) { // 全屏显示 - this.viewportMetrics.physicalViewPaddingTop = systemAvoidArea?.topRect.height ?? 0; - this.viewportMetrics.physicalViewPaddingBottom = navigationAvoidArea?.bottomRect.height ?? 0; + if (this.checkFullScreen && (setFullScreen || FlutterManager.getInstance().getFullScreenListener().useFullScreen())) { // 全屏显示 + this.viewportMetrics.physicalViewPaddingTop = this.systemAvoidArea?.topRect.height ?? 0; + this.viewportMetrics.physicalViewPaddingBottom = this.navigationAvoidArea?.bottomRect.height ?? 0; } else { // 非全屏显示(保持规避效果) // 顶部状态栏和底部导航栏规避为0,无平滑过渡效果 this.viewportMetrics.physicalViewPaddingTop = 0; this.viewportMetrics.physicalViewPaddingBottom = 0; } - this.viewportMetrics.physicalViewPaddingLeft = systemAvoidArea?.leftRect.width ?? 0; - this.viewportMetrics.physicalViewPaddingRight = systemAvoidArea?.rightRect.width ?? 0; + this.viewportMetrics.physicalViewPaddingLeft = this.systemAvoidArea?.leftRect.width ?? 0; + this.viewportMetrics.physicalViewPaddingRight = this.systemAvoidArea?.rightRect.width ?? 0; this.onKeyboardAreaChange() this.onGestureAreaChange() - this.updateViewportMetrics() + if (!this.viewportMetrics.isEqual(originalMetrics)) { + this.updateViewportMetrics() + } } private onKeyboardAreaChange() { diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index 390b300b202a7a2b3c98fd6516deafedfff8f975..473feb562ef2e514295f71ca29a328f405596f71 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -138,7 +138,9 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_FUNCTION( "nativeDecodeUtf8", flutter::PlatformViewOHOSNapi::nativeDecodeUtf8), - + DECLARE_NAPI_FUNCTION( + "nativeLookupCallbackInformation", + flutter::PlatformViewOHOSNapi::nativeLookupCallbackInformation), }; FML_DLOG(INFO) << "Init NAPI size=" << sizeof(desc) / sizeof(desc[0]); diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 9ac9dfafd2b1a88ca92ccf9a6b13e0587581cf92..d46617ef3a738051ec6cfe7fff79c14bea7b4778 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -29,6 +29,7 @@ #include "flutter/shell/platform/ohos/ohos_shell_holder.h" #include "flutter/shell/platform/ohos/surface/ohos_native_window.h" #include "flutter/shell/platform/ohos/types.h" +#include "flutter/lib/ui/plugins/callback_cache.h" #include "unicode/uchar.h" #include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" #include "flutter/shell/platform/ohos/ohos_logging.h" @@ -1797,4 +1798,56 @@ napi_value PlatformViewOHOSNapi::nativeDecodeUtf8(napi_env env, napi_callback_in return result; } +napi_value PlatformViewOHOSNapi::nativeLookupCallbackInformation(napi_env env, napi_callback_info info) +{ + napi_value result; + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_status ret = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + if (ret != napi_ok) { + LOGE("nativeLookupCallbackInformation napi_get_cb_info error"); + napi_create_int32(env, -1, &result); + return result; + } + + int64_t handle; + bool lossless; + ret = napi_get_value_bigint_int64(env, args[1], &handle, &lossless); + if (ret != napi_ok) { + LOGE("nativeLookupCallbackInformation napi_get_value_int64 error"); + napi_create_int32(env, -1, &result); + return result; + } + + LOGD("nativeLookupCallbackInformation::handle : %{public}ld", handle); + auto cbInfo = flutter::DartCallbackCache::GetCallbackInformation(handle); + if (cbInfo == nullptr) { + LOGE("nativeLookupCallbackInformation DartCallbackCache GetCallbackInformation nullptr"); + napi_create_int32(env, -1, &result); + return result; + } + + napi_ref callbck_napi_obj; + ret = napi_create_reference(env, args[0], 1, &callbck_napi_obj); + if (ret != napi_ok) { + LOGE("nativeLookupCallbackInformation napi_create_reference error"); + napi_create_int32(env, -1, &result); + return result; + } + + napi_value callbackParam[3]; + napi_create_string_utf8(env, cbInfo->name.c_str(), NAPI_AUTO_LENGTH, &callbackParam[0]); + napi_create_string_utf8(env, cbInfo->class_name.c_str(), NAPI_AUTO_LENGTH, &callbackParam[1]); + napi_create_string_utf8(env, cbInfo->library_path.c_str(), NAPI_AUTO_LENGTH, &callbackParam[2]); + + ret = fml::napi::InvokeJsMethod(env, callbck_napi_obj, "init", 3, callbackParam); + if (ret != napi_ok) { + FML_DLOG(ERROR) << "nativeLookupCallbackInformation init fail "; + napi_create_int32(env, -1, &result); + return result; + } + napi_delete_reference(env, callbck_napi_obj); + napi_create_int32(env, 0, &result); + return result; +} } // namespace flutter \ No newline at end of file diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index 2c9cc19fb5e2a536269d3e1119d52211dea15dc3..9ca6b6f90b41da0860243cbcbe67e953b59eddb0 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -208,6 +208,9 @@ class PlatformViewOHOSNapi { static napi_value nativeDecodeUtf8( napi_env env, napi_callback_info info); + static napi_value nativeLookupCallbackInformation( + napi_env env, + napi_callback_info info); private: static napi_env env_;