From a715e72160aef50cabfb4e0151e32522dd493fcb Mon Sep 17 00:00:00 2001 From: zhuhousheng Date: Fri, 1 Aug 2025 09:55:09 +0800 Subject: [PATCH] hasimage Signed-off-by: zhuhousheng --- interfaces/kits/ani/webview/BUILD.gn | 2 + .../ani/webview/ets/@ohos.web.webview.ets | 7 + .../webviewcontroller/webview_controller.cpp | 42 ++--- .../webviewcontroller/webview_controller.h | 4 +- .../webview_hasimage_callback.cpp | 161 ++++++++---------- .../webview_hasimage_callback.h | 28 ++- .../ani_webview_controller.cpp | 59 +++++++ 7 files changed, 176 insertions(+), 127 deletions(-) diff --git a/interfaces/kits/ani/webview/BUILD.gn b/interfaces/kits/ani/webview/BUILD.gn index 836e74ee0..fe6d0b54f 100644 --- a/interfaces/kits/ani/webview/BUILD.gn +++ b/interfaces/kits/ani/webview/BUILD.gn @@ -115,6 +115,7 @@ ohos_shared_library("webview_ani") { "native/webviewcontroller/web_scheme_handler_request.h", "native/webviewcontroller/webview_controller.cpp", "native/webviewcontroller/webview_hasimage_callback.cpp", + "native/webviewcontroller/webview_hasimage_callback.h", #"native/webviewcontroller/webview_javascript_execute_callback.cpp", "native/webviewcontroller/webview_javascript_result_callback.cpp", ] @@ -127,6 +128,7 @@ ohos_shared_library("webview_ani") { "../../napi/protos:proto_gen", ] external_deps = [ + "eventhandler:libeventhandler", "runtime_core:ani_helpers", "ability_base:extractortool", "ability_runtime:app_context", diff --git a/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets b/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets index f293c4c63..807c0e0d1 100644 --- a/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets +++ b/interfaces/kits/ani/webview/ets/@ohos.web.webview.ets @@ -730,6 +730,13 @@ export default namespace webview { runJavaScriptExt(script: string | ArrayBuffer, callback: AsyncCallback): void { this.runJavaScriptCallbackExt(script, callback); } + native hasImageInternal(callback: AsyncCallback): void; + native hasImageInternals(): Promise; + hasImage(callback: AsyncCallback): void { + this.hasImageInternal(callback);} + hasImage(): Promise { + return this.hasImageInternals(); + } } export class WebSchemeHandlerResponse { diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp index 368fff232..926d65251 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp +++ b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.cpp @@ -957,48 +957,42 @@ void WebviewController::PutNetworkAvailable(bool available) } } -ErrCode WebviewController::HasImagesCallback(napi_env env, napi_ref jsCallback) +ErrCode WebviewController::HasImagesCallback(ani_env* env,ani_ref jsCallback) { + WVLOG_E("HasImagesCallback start"); + ani_resolver resolver; auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_); if (!nweb_ptr) { - napi_value setResult[RESULT_COUNT] = {0}; - setResult[PARAMZERO] = BusinessError::CreateError(env, NWebError::INIT_ERROR); - napi_get_null(env, &setResult[PARAMONE]); - - napi_value args[RESULT_COUNT] = {setResult[PARAMZERO], setResult[PARAMONE]}; - napi_value callback = nullptr; - napi_get_reference_value(env, jsCallback, &callback); - napi_value callbackResult = nullptr; - napi_call_function(env, nullptr, callback, RESULT_COUNT, args, &callbackResult); - napi_delete_reference(env, jsCallback); - return NWebError::INIT_ERROR; + WVLOG_I("HasImagesCallback controller fail"); + return NWEB_ERROR; } - if (jsCallback == nullptr) { return NWebError::PARAM_CHECK_ERROR; } - - auto callbackImpl = std::make_shared(env, jsCallback, nullptr); + auto callbackImpl = std::make_shared(env, jsCallback, resolver); nweb_ptr->HasImages(callbackImpl); + WVLOG_E("HasImagesCallback trigger"); return NWebError::NO_ERROR; } -ErrCode WebviewController::HasImagesPromise(napi_env env, napi_deferred deferred) +ErrCode WebviewController::HasImagesPromise(ani_env* env,ani_resolver resolver) { + WVLOG_E("HasImagesPromise start"); auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_); if (!nweb_ptr) { - napi_value jsResult = nullptr; - jsResult = NWebError::BusinessError::CreateError(env, NWebError::INIT_ERROR); - napi_reject_deferred(env, deferred, jsResult); - return NWebError::INIT_ERROR; + WVLOG_I("HasImagesPromise controller fail"); + return NWEB_ERROR; } - - if (deferred == nullptr) { + if (resolver == nullptr) { + return NWebError::PARAM_CHECK_ERROR; + } + auto callbackImpl = std::make_shared(env, nullptr, resolver); + if (!callbackImpl) { + WVLOG_E("HasImagesPromise !callbackImpl"); return NWebError::PARAM_CHECK_ERROR; } - - auto callbackImpl = std::make_shared(env, nullptr, deferred); nweb_ptr->HasImages(callbackImpl); + WVLOG_E("HasImagesPromise trigger"); return NWebError::NO_ERROR; } diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h index 899853ddd..2519cf8f9 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h +++ b/interfaces/kits/ani/webview/native/webviewcontroller/webview_controller.h @@ -232,9 +232,9 @@ public: bool HasImage(std::shared_ptr callback); - ErrCode HasImagesCallback(napi_env env, napi_ref jsCallback); + ErrCode HasImagesCallback(ani_env* env, ani_ref jsCallback); - ErrCode HasImagesPromise(napi_env env, napi_deferred deferred); + ErrCode HasImagesPromise(ani_env* env, ani_resolver resolver); void RemoveCache(bool includeDiskFiles); diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.cpp b/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.cpp index 190952058..88d576bf7 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.cpp +++ b/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.cpp @@ -12,117 +12,106 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include "event_handler.h" +#include #include "webview_hasimage_callback.h" #include "business_error.h" -#include "napi_parse_utils.h" #include "nweb_log.h" -#include "nweb_napi_scope.h" #include "web_errors.h" namespace OHOS::NWeb { +const int CALLBACK_PARAM_LENGTH = 2; using namespace NWebError; - -void WebviewHasImageCallback::OnReceiveValue(bool result) -{ - uv_loop_s *loop = nullptr; - uv_work_t *work = nullptr; - - napi_get_uv_event_loop(env_, &loop); - if (loop == nullptr) { - return; - } - work = new (std::nothrow) uv_work_t; - if (work == nullptr) { - return; - } - +void WebviewHasImageCallback::OnReceiveValue(bool result) { + WVLOG_E("OnReceiveValue begin"); + WVLOG_I("OnReceiveValue result: %{public}d", result); HasImageParam *param = new (std::nothrow) HasImageParam(); - if (param == nullptr) { - delete work; - work = nullptr; - return; - } param->env_ = env_; + ani_vm *vm =nullptr; + env_->GetVM(&vm); param->callbackRef_ = callbackRef_; - param->deferred_ = deferred_; + param->resolver_ = resolver_; param->result_ = result; - work->data = reinterpret_cast(param); - - int ret = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, UvAfterWorkCb, uv_qos_user_initiated); - if (ret != 0) { - if (param != nullptr) { - delete param; - param = nullptr; + // WVLOG_E("callbackRef_: %{public}p, resolver_: %{public}p", param->callbackRef_, param->resolver_); + // auto task = [param, vm]() { + // WVLOG_E("Task begin, vm: %{public}p", vm); + + // delete param; + // }; + ani_env *env; + vm->GetEnv(ANI_VERSION_1, &env); + WVLOG_E("Task env: %{public}p", env); + if (param->callbackRef_) { + UvAfterWorkCbAsync(env, param->callbackRef_, param->result_); + } else if (param->resolver_) { + UvAfterWorkCbPromise(env, param->resolver_, param->result_); } - if (work != nullptr) { - delete work; - work = nullptr; - } - } + // std::shared_ptr runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); + // if (!runner) { + // HILOG_WARN(LOG_CORE, "hasimage OnReceiveValue invalid main event runner."); + // } + // std::shared_ptr mainHandler = nullptr; + // mainHandler = std::make_shared(runner); + // if (mainHandler->PostTask(task, "hasimage task",0, OHOS::AppExecFwk::EventQueue::Priority::IMMEDIATE, {})) { + // WVLOG_I("OnReceiveValue success"); + // } else { + // WVLOG_I("OnReceiveValue failed"); + // return; + // } + WVLOG_E("OnReceiveValue finish"); } -void WebviewHasImageCallback::UvAfterWorkCb(uv_work_t* work, int status) +void WebviewHasImageCallback::UvAfterWorkCbAsync(ani_env *env, ani_ref callbackRef, + bool result) { - (void)status; - if (!work) { - return; - } - HasImageParam *param = reinterpret_cast(work->data); - if (!param) { - delete work; - work = nullptr; - return; + if (callbackRef == nullptr) { + WVLOG_E("callbackRef is nullptr"); + return; } - napi_handle_scope scope = nullptr; - napi_open_handle_scope(param->env_, &scope); - if (scope == nullptr) { - return; + WVLOG_E("UvAfterWorkCbAsync begin"); + std::vector resultRef(CALLBACK_PARAM_LENGTH); + env->GetNull(&resultRef[0]); + ani_class bool_cls; + ani_status status; + if ((status = env->FindClass("Lstd/core/Boolean;", &bool_cls)) != ANI_OK) { + WVLOG_E("error in FindClass status : %{public}d", status); + return ; } - if (param->callbackRef_) { - UvAfterWorkCbAsync(param->env_, param->callbackRef_, param->result_); - } else if (param->deferred_) { - UvAfterWorkCbPromise(param->env_, param->deferred_, param->result_); - } - - napi_close_handle_scope(param->env_, scope); - delete param; - param = nullptr; - delete work; - work = nullptr; -} - -void WebviewHasImageCallback::UvAfterWorkCbAsync(napi_env env, napi_ref callbackRef, - bool result) -{ - OHOS::NApiScope scope(env); - napi_value setResult[INTEGER_TWO] = {0}; - napi_get_undefined(env, &setResult[INTEGER_ZERO]); - napi_status getBooleanResult = napi_get_boolean(env, result, &setResult[INTEGER_ONE]); - if (getBooleanResult != napi_ok) { - napi_get_boolean(env, false, &setResult[INTEGER_ONE]); + ani_method boolInfoCtor; + if ((status = env->Class_FindMethod(bool_cls, "", "Z:V", &boolInfoCtor)) != ANI_OK) { + WVLOG_E("error in FindMethod status : %{public}d", status); + return ; } - napi_value args[INTEGER_TWO] = {setResult[INTEGER_ZERO], setResult[INTEGER_ONE]}; - napi_value callback = nullptr; - napi_get_reference_value(env, callbackRef, &callback); - napi_value callbackResult = nullptr; - napi_call_function(env, nullptr, callback, INTEGER_TWO, args, &callbackResult); - napi_delete_reference(env, callbackRef); + ani_object boolInfoObj; + env->Object_New(bool_cls, boolInfoCtor, &boolInfoObj, static_cast(result)); + resultRef[1] = static_cast(boolInfoObj); + if (callbackRef) { + ani_ref fnReturnVal; + if ((status = env->FunctionalObject_Call(static_cast(callbackRef), resultRef.size(), + resultRef.data(), &fnReturnVal)) != ANI_OK) { + WVLOG_E("error callback FunctionalObject_Call Failed status : %{public}d!", status); + } else { + WVLOG_I("error callback FunctionalObject_Call Success!"); + }} + env->GlobalReference_Delete(callbackRef); + WVLOG_E("UvAfterWorkCbAsync finish"); } - -void WebviewHasImageCallback::UvAfterWorkCbPromise(napi_env env, napi_deferred deferred, +void WebviewHasImageCallback::UvAfterWorkCbPromise(ani_env *env, ani_resolver resolver, bool result) { - napi_value setResult; - napi_status getBooleanResult = napi_get_boolean(env, result, &setResult); - if (getBooleanResult != napi_ok) { - napi_get_boolean(env, false, &setResult); - } - napi_resolve_deferred(env, deferred, setResult); + WVLOG_E("UvAfterWorkCbPromise begin"); + ani_object promise; + env->Promise_New(&resolver, &promise); + std::string resolved = result ? "true" : "false"; + ani_string resolution; + // may fault + env->String_NewUTF8(resolved.c_str(), resolved.size(), &resolution); + env->PromiseResolver_Resolve(resolver, resolution); + WVLOG_E("UvAfterWorkCbPromise finish"); } } // namespace NWeb \ No newline at end of file diff --git a/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.h b/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.h index 65648b0d2..1f3de7c96 100644 --- a/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.h +++ b/interfaces/kits/ani/webview/native/webviewcontroller/webview_hasimage_callback.h @@ -15,35 +15,33 @@ #ifndef NWEB_WEBVIEW_HAS_IMAGE_CALLBACK_H #define NWEB_WEBVIEW_HAS_IMAGE_CALLBACK_H -#include -#include "napi/native_api.h" -#include "napi/native_node_api.h" +#include #include "nweb_value_callback.h" namespace OHOS::NWeb { class WebviewHasImageCallback : public NWebBoolValueCallback { public: - explicit WebviewHasImageCallback(napi_env env, napi_ref callbackRef, napi_deferred deferred) - : env_(env), callbackRef_(callbackRef), deferred_(deferred) {} + explicit WebviewHasImageCallback(ani_env *env, ani_ref callbackRef, ani_resolver resolver) + : env_(env), callbackRef_(callbackRef), resolver_(resolver) {} ~WebviewHasImageCallback() = default; void OnReceiveValue(bool result) override; private: + struct HasImageParam { - napi_env env_; - napi_ref callbackRef_; - napi_deferred deferred_; + ani_env *env_; + ani_ref callbackRef_; + ani_resolver resolver_; bool result_; }; - napi_env env_ = nullptr; - napi_ref callbackRef_ = nullptr; - napi_deferred deferred_ = nullptr; + ani_env* env_ = nullptr; + ani_ref callbackRef_ = nullptr; + ani_resolver resolver_ = nullptr; - static void UvAfterWorkCb(uv_work_t* work, int status); - static void UvAfterWorkCbAsync(napi_env env, napi_ref callbackRef, bool result); - static void UvAfterWorkCbPromise(napi_env env, napi_deferred deferred, bool result); + static void UvAfterWorkCbAsync(ani_env *env, ani_ref callbackRef,bool result); + static void UvAfterWorkCbPromise(ani_env *env, ani_resolver resolver,bool result); }; } -#endif +#endif \ No newline at end of file diff --git a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp index 70e6cd70b..63b0f3b32 100644 --- a/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp +++ b/interfaces/kits/ani/webview/src/webviewcontroller/ani_webview_controller.cpp @@ -4788,6 +4788,63 @@ static void RunJavaScriptCallbackExt(ani_env* env, ani_object object, ani_object return RunJSCallback(env, object, script, callbackObj, true); } +static void HasImageInternal(ani_env* env, ani_object object,ani_object callback) +{ + WVLOG_E("HasImageInternal begin"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return; + } + auto* controller = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + + if (!controller || !controller->IsInit()) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return; + } + ani_ref jsCallback = nullptr; + env->GlobalReference_Create(callback, &jsCallback); + if (jsCallback) { + ErrCode ret = controller->HasImagesCallback(env, std::move(jsCallback)); + WVLOG_E("HasImagesCallback trigger"); + if (ret == NWEB_ERROR) { + return; + } else if (ret != NO_ERROR) { + AniBusinessError::ThrowErrorByErrCode(env, ret); + return; + } + } + return; +} + +static ani_object HasImageInternals(ani_env* env, ani_object object,ani_object callback) +{ + WVLOG_E("HasImageInternals begin"); + if (env == nullptr) { + WVLOG_E("env is nullptr"); + return nullptr; + } + auto* controller = reinterpret_cast(AniParseUtils::Unwrap(env, object)); + + if (!controller || !controller->IsInit()) { + AniBusinessError::ThrowErrorByErrCode(env, INIT_ERROR); + return nullptr; + } + ani_object promise = nullptr; + ani_resolver resolver = nullptr; + env->Promise_New(&resolver, &promise); + if (promise && resolver) { + ErrCode ret = controller->HasImagesPromise(env,resolver); + WVLOG_E("HasImagesPromise trigger"); + if (ret == NWEB_ERROR) { + return nullptr; + } else if (ret != NO_ERROR) { + AniBusinessError::ThrowErrorByErrCode(env, ret); + return nullptr; + } + } + return promise; +} + ani_status StsWebviewControllerInit(ani_env *env) { WVLOG_D("[DOWNLOAD] StsWebviewControllerInit"); @@ -4900,6 +4957,8 @@ ani_status StsWebviewControllerInit(ani_env *env) reinterpret_cast(SetServiceWorkerWebSchemeHandler) }, ani_native_function { "runJavaScriptCallback", nullptr, reinterpret_cast(RunJavaScriptCallback) }, ani_native_function { "runJavaScriptCallbackExt", nullptr, reinterpret_cast(RunJavaScriptCallbackExt) }, + ani_native_function { "hasImageInternal", nullptr, reinterpret_cast(HasImageInternal) }, + ani_native_function { "hasImageInternals", nullptr, reinterpret_cast(HasImageInternals) }, }; status = env->Class_BindNativeMethods(webviewControllerCls, controllerMethods.data(), controllerMethods.size()); if (status != ANI_OK) { -- Gitee