已合并
补充arkts1.2文件上传弹窗 #77603
SprucEovo创建于 2025年12月10日
补充arkts1.2文件上传弹窗 #77603
已合并
共 9 个文件变更+152-0
| @@ -62,6 +62,74 @@ static void GetCommonFunc(ani_vm* vm, ani_ref savePtr, | |||
| 62 | webviewControllerPeer->releaseRefFunc = std::move(releaseRefFunc); | 62 | webviewControllerPeer->releaseRefFunc = std::move(releaseRefFunc); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | +static bool GetFileSelectorObject(ani_env* env, const char* classDesc, ani_object* obj, void* args) | ||
| 66 | +{ | ||
| 67 | + ani_class cls; | ||
| 68 | + if (env->FindClass(classDesc, &cls) != ANI_OK) { | ||
| 69 | + HILOGE("FindClass fail: %{public}s", classDesc); | ||
| 70 | + return false; | ||
| 71 | + } | ||
| 72 | + ani_method ctor; | ||
| 73 | + if (env->Class_FindMethod(cls, "<ctor>", "l:", &ctor) != ANI_OK) { | ||
| 74 | + HILOGE("Class_FindMethod fail, <ctor> in %{public}s", classDesc); | ||
| 75 | + return false; | ||
| 76 | + } | ||
| 77 | + if (env->Object_New(cls, ctor, obj, args) != ANI_OK) { | ||
| 78 | + HILOGE("Object_New fail: %{public}s", classDesc); | ||
| 79 | + return false; | ||
| 80 | + } | ||
| 81 | + return true; | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +static void DefaultOnShowFileSelector(ani_vm* vm, void* paramPeer, void* resultPeer, std::function<void(void*)> release) | ||
| 85 | +{ | ||
| 86 | + HILOGI("Call defaultOnShowFileSelector start"); | ||
| 87 | + ani_env* env = GetAniEnv(vm); | ||
| 88 | + if (!env) { | ||
| 89 | + HILOGE("DefaultOnShowFileSelector callback env is nullptr"); | ||
| 90 | + release(paramPeer); | ||
| 91 | + release(resultPeer); | ||
| 92 | + return; | ||
| 93 | + } | ||
| 94 | + ani_object paramObj; | ||
| 95 | + if (!GetFileSelectorObject(env, "arkui.component.web.FileSelectorParam", ¶mObj, paramPeer)) { | ||
| 96 | + release(paramPeer); | ||
| 97 | + release(resultPeer); | ||
| 98 | + return; | ||
| 99 | + } | ||
| 100 | + ani_object resultObj; | ||
| 101 | + if (!GetFileSelectorObject(env, "arkui.component.web.FileSelectorResult", &resultObj, resultPeer)) { | ||
| 102 | + release(resultPeer); | ||
| 103 | + return; | ||
| 104 | + } | ||
| 105 | + ani_class cls; | ||
| 106 | + if (env->FindClass("@ohos.web.fileSelector.SelectorDialog", &cls) != ANI_OK) { | ||
| 107 | + HILOGE("FindClass fail: SelectorDialog"); | ||
后面分支为什么不需要release ![]() ![]() | |||
| 108 | + return; | ||
| 109 | + } | ||
| 110 | + ani_method method; | ||
| 111 | + if (env->Class_FindMethod(cls, "<ctor>", ":", &method) != ANI_OK) { | ||
| 112 | + HILOGE("Class_FindMethod fail, <ctor> in SelectorDialog"); | ||
| 113 | + return; | ||
| 114 | + } | ||
| 115 | + ani_object obj; | ||
| 116 | + if (env->Object_New(cls, method, &obj) != ANI_OK) { | ||
| 117 | + HILOGE("Object_New fail: SelectorDialog"); | ||
| 118 | + return; | ||
| 119 | + } | ||
| 120 | + if (env->Class_FindMethod(cls, "defaultOnShowFileSelector", | ||
| 121 | + "C{arkui.component.web.FileSelectorParam}C{arkui.component.web.FileSelectorResult}:", | ||
| 122 | + &method) != ANI_OK) { | ||
| 123 | + HILOGE("Class_FindMethod fail, defaultOnShowFileSelector"); | ||
| 124 | + return; | ||
| 125 | + } | ||
| 126 | + if (env->Object_CallMethod_Void(obj, method, paramObj, resultObj) != ANI_OK) { | ||
| 127 | + HILOGE("Call defaultOnShowFileSelector fail"); | ||
| 128 | + return; | ||
| 129 | + } | ||
| 130 | + HILOGI("Call defaultOnShowFileSelector done"); | ||
| 131 | +} | ||
| 132 | + | ||
| 65 | static void GetWebOptionsFunc(ani_vm* vm, ani_ref savePtr, | 133 | static void GetWebOptionsFunc(ani_vm* vm, ani_ref savePtr, |
| 66 | WebviewControllerPeer* webviewControllerPeer) | 134 | WebviewControllerPeer* webviewControllerPeer) |
| 67 | { | 135 | { |
| @@ -96,9 +164,13 @@ static void GetWebOptionsFunc(ani_vm* vm, ani_ref savePtr, | |||
| 96 | } | 164 | } |
| 97 | envTemp->GlobalReference_Delete(object); | 165 | envTemp->GlobalReference_Delete(object); |
| 98 | }; | 166 | }; |
| 167 | + auto defaultOnShowFileSelectorFunc = [vm](void* paramPeer, void* resultPeer, std::function<void(void*)> release) { | ||
| 168 | + DefaultOnShowFileSelector(vm, paramPeer, resultPeer, std::move(release)); | ||
| 169 | + }; | ||
| 99 | webviewControllerPeer->setWebIdFunc = std::move(setWebIdFunc); | 170 | webviewControllerPeer->setWebIdFunc = std::move(setWebIdFunc); |
| 100 | webviewControllerPeer->setHapPathFunc = std::move(setHapPathFunc); | 171 | webviewControllerPeer->setHapPathFunc = std::move(setHapPathFunc); |
| 101 | webviewControllerPeer->setWebDetachFunc = std::move(setWebDetachFunc); | 172 | webviewControllerPeer->setWebDetachFunc = std::move(setWebDetachFunc); |
| 173 | + webviewControllerPeer->defaultOnShowFileSelectorFunc = std::move(defaultOnShowFileSelectorFunc); | ||
| 102 | } | 174 | } |
| 103 | 175 | ||
| 104 | static void GetWebviewControllerHandlerFunc(ani_vm* vm, ani_ref savePtr, | 176 | static void GetWebviewControllerHandlerFunc(ani_vm* vm, ani_ref savePtr, |
| @@ -915,6 +915,18 @@ void WebModelStatic::SetOnFileSelectorShow( | |||
| 915 | webEventHub->SetOnFileSelectorShowEvent(std::move(uiCallback)); | 915 | webEventHub->SetOnFileSelectorShowEvent(std::move(uiCallback)); |
| 916 | } | 916 | } |
| 917 | 917 | ||
| 918 | +void WebModelStatic::SetDefaultFileSelectorShow( | ||
| 919 | + FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback) | ||
const BaseEventInfo* info可以替换成const std::shared_ptr ![]() ![]() | |||
| 920 | +{ | ||
| 921 | + CHECK_NULL_VOID(frameNode); | ||
| 922 | + auto uiCallback = [func = callback](const std::shared_ptr<BaseEventInfo>& info) { | ||
| 923 | + func(info.get()); | ||
| 924 | + }; | ||
| 925 | + auto webPatternStatic = AceType::DynamicCast<WebPatternStatic>(frameNode->GetPattern()); | ||
| 926 | + CHECK_NULL_VOID(webPatternStatic); | ||
| 927 | + webPatternStatic->SetDefaultFileSelectorShowCallback(std::move(uiCallback)); | ||
| 928 | +} | ||
| 929 | + | ||
| 918 | void WebModelStatic::SetOnDetectedBlankScreen( | 930 | void WebModelStatic::SetOnDetectedBlankScreen( |
| 919 | FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback) | 931 | FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback) |
| 920 | { | 932 | { |
| @@ -130,6 +130,8 @@ public: | |||
| 130 | static void SetRenderExitedId(FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback); | 130 | static void SetRenderExitedId(FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback); |
| 131 | static void SetOnFileSelectorShow( | 131 | static void SetOnFileSelectorShow( |
| 132 | FrameNode* frameNode, std::function<bool(const BaseEventInfo* info)>&& callback); | 132 | FrameNode* frameNode, std::function<bool(const BaseEventInfo* info)>&& callback); |
| 133 | + static void SetDefaultFileSelectorShow( | ||
| 134 | + FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback); | ||
| 133 | static void SetOnDetectedBlankScreen( | 135 | static void SetOnDetectedBlankScreen( |
| 134 | FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback); | 136 | FrameNode* frameNode, std::function<void(const BaseEventInfo* info)>&& callback); |
| 135 | static void SetBlankScreenDetectionConfig(FrameNode* frameNode, const BlankScreenDetectionConfig& detectConfig); | 137 | static void SetBlankScreenDetectionConfig(FrameNode* frameNode, const BlankScreenDetectionConfig& detectConfig); |
| @@ -87,6 +87,7 @@ typedef struct webview_WebviewControllerPeer { | |||
| 87 | std::function<void(int32_t)> setWebIdFunc = nullptr; | 87 | std::function<void(int32_t)> setWebIdFunc = nullptr; |
| 88 | std::function<void(const std::string&)> setHapPathFunc = nullptr; | 88 | std::function<void(const std::string&)> setHapPathFunc = nullptr; |
| 89 | std::function<void(int32_t)> setWebDetachFunc = nullptr; | 89 | std::function<void(int32_t)> setWebDetachFunc = nullptr; |
| 90 | + std::function<void(void*, void*, std::function<void(void*)>)> defaultOnShowFileSelectorFunc = nullptr; | ||
| 90 | } WebviewControllerPeer; | 91 | } WebviewControllerPeer; |
| 91 | 92 | ||
| 92 | typedef struct NodeAdapterInfo { | 93 | typedef struct NodeAdapterInfo { |
| @@ -265,6 +265,12 @@ void SetWebOptionsImpl(Ark_NativePointer node, | |||
| 265 | WebModelStatic::SetWebIdCallback(frameNode, std::move(controller->setWebIdFunc)); | 265 | WebModelStatic::SetWebIdCallback(frameNode, std::move(controller->setWebIdFunc)); |
| 266 | WebModelStatic::SetHapPathCallback(frameNode, std::move(controller->setHapPathFunc)); | 266 | WebModelStatic::SetHapPathCallback(frameNode, std::move(controller->setHapPathFunc)); |
| 267 | WebModelStatic::SetWebDetachCallback(frameNode, std::move(controller->setWebDetachFunc)); | 267 | WebModelStatic::SetWebDetachCallback(frameNode, std::move(controller->setWebDetachFunc)); |
| 268 | + auto fileSelectorShowFromUserCallback = [callback = std::move(controller->defaultOnShowFileSelectorFunc), | ||
| 269 | + weakNode = AceType::WeakClaim(frameNode), | ||
| 270 | + instanceId = Container::CurrentId()](const BaseEventInfo* info) { | ||
| 271 | + WebAttributeModifier::DefaultOnShowFileSelector(std::move(callback), weakNode, instanceId, info); | ||
| 272 | + }; | ||
| 273 | + WebModelStatic::SetDefaultFileSelectorShow(frameNode, std::move(fileSelectorShowFromUserCallback)); | ||
| 268 | /* This controller is only used to pass the hook function for initializing the webviewController. | 274 | /* This controller is only used to pass the hook function for initializing the webviewController. |
| 269 | * After passing, the corresponding memory needs to be released. | 275 | * After passing, the corresponding memory needs to be released. |
| 270 | */ | 276 | */ |
| @@ -385,6 +385,34 @@ bool OnShowFileSelector(const CallbackHelper<Callback_OnShowFileSelectorEvent_Bo | |||
| 385 | return result.value_or(false); | 385 | return result.value_or(false); |
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | +void DefaultOnShowFileSelector(const std::function<void(void*, void*, std::function<void(void*)>)>& callback, | ||
| 389 | + WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info) | ||
| 390 | +{ | ||
| 391 | + CHECK_NULL_VOID(callback); | ||
| 392 | + const auto refNode = weakNode.Upgrade(); | ||
| 393 | + CHECK_NULL_VOID(refNode); | ||
| 394 | + ContainerScope scope(instanceId); | ||
| 395 | + auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck(); | ||
| 396 | + CHECK_NULL_VOID(pipelineContext); | ||
| 397 | + pipelineContext->UpdateCurrentActiveNode(weakNode); | ||
| 398 | + auto* eventInfo = TypeInfoHelper::DynamicCast<FileSelectorEvent>(info); | ||
| 399 | + CHECK_NULL_VOID(eventInfo); | ||
| 400 | + auto paramPeer = new FileSelectorParamPeer(); | ||
| 401 | + paramPeer->handler = eventInfo->GetParam(); | ||
paramPeer 判空 ![]() ![]() | |||
| 402 | + auto resultPeer = new FileSelectorResultPeer(); | ||
| 403 | + resultPeer->handler = eventInfo->GetFileSelectorResult(); | ||
resultPeer判空 ![]() ![]() | |||
| 404 | + auto releaseFunc = [¶mPeer, &resultPeer](void* peer) { | ||
| 405 | + if (paramPeer == peer) { | ||
| 406 | + delete paramPeer; | ||
| 407 | + paramPeer = nullptr; | ||
| 408 | + } else if (resultPeer == peer) { | ||
| 409 | + delete resultPeer; | ||
| 410 | + resultPeer = nullptr; | ||
| 411 | + } | ||
| 412 | + }; | ||
| 413 | + callback(paramPeer, resultPeer, std::move(releaseFunc)); | ||
| 414 | +} | ||
| 415 | + | ||
| 388 | void OnDetectedBlankScreen(const CallbackHelper<OnDetectBlankScreenCallback>& arkCallback, | 416 | void OnDetectedBlankScreen(const CallbackHelper<OnDetectBlankScreenCallback>& arkCallback, |
| 389 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info) | 417 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info) |
| 390 | { | 418 | { |
| @@ -63,6 +63,8 @@ void OnRenderExited(const CallbackHelper<Callback_OnRenderExitedEvent_Void>& ark | |||
| 63 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info); | 63 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info); |
| 64 | bool OnShowFileSelector(const CallbackHelper<Callback_OnShowFileSelectorEvent_Boolean>& arkCallback, | 64 | bool OnShowFileSelector(const CallbackHelper<Callback_OnShowFileSelectorEvent_Boolean>& arkCallback, |
| 65 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info); | 65 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info); |
| 66 | +void DefaultOnShowFileSelector(const std::function<void(void*, void*, std::function<void(void*)>)>& callback, | ||
| 67 | + WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info); | ||
| 66 | void OnDetectedBlankScreen(const CallbackHelper<OnDetectBlankScreenCallback>& arkCallback, | 68 | void OnDetectedBlankScreen(const CallbackHelper<OnDetectBlankScreenCallback>& arkCallback, |
| 67 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info); | 69 | WeakPtr<FrameNode> weakNode, int32_t instanceId, const BaseEventInfo* info); |
| 68 | void OnResourceLoad(const CallbackHelper<Callback_OnResourceLoadEvent_Void>& arkCallback, | 70 | void OnResourceLoad(const CallbackHelper<Callback_OnResourceLoadEvent_Void>& arkCallback, |
| @@ -31,6 +31,7 @@ class WebPattern : public Pattern { | |||
| 31 | public: | 31 | public: |
| 32 | using SetWebDetachCallback = std::function<void(int32_t)>; | 32 | using SetWebDetachCallback = std::function<void(int32_t)>; |
| 33 | using OnControllerAttachedCallback = std::function<void()>; | 33 | using OnControllerAttachedCallback = std::function<void()>; |
| 34 | + using DefaultFileSelectorShowCallback = std::function<void(const std::shared_ptr<BaseEventInfo>&)>; | ||
| 34 | WebPattern(); | 35 | WebPattern(); |
| 35 | ~WebPattern() override; | 36 | ~WebPattern() override; |
| 36 | 37 | ||
| @@ -140,6 +141,7 @@ public: | |||
| 140 | } | 141 | } |
| 141 | 142 | ||
| 142 | void SetPreviewSelectionMenu(const std::shared_ptr<WebPreviewSelectionMenuParam>& param) {} | 143 | void SetPreviewSelectionMenu(const std::shared_ptr<WebPreviewSelectionMenuParam>& param) {} |
| 144 | + void SetDefaultFileSelectorShowCallback(DefaultFileSelectorShowCallback&& Callback) {} | ||
| 143 | 145 | ||
| 144 | void SetOnControllerAttachedCallback(OnControllerAttachedCallback&& callback); | 146 | void SetOnControllerAttachedCallback(OnControllerAttachedCallback&& callback); |
| 145 | OnControllerAttachedCallback GetOnControllerAttachedCallback(); | 147 | OnControllerAttachedCallback GetOnControllerAttachedCallback(); |
| @@ -2298,6 +2298,33 @@ HWTEST_F(WebModelStaticTest, SetOnFileSelectorShow001, TestSize.Level1) | |||
| 2298 | 2298 | ||
| 2299 | } | 2299 | } |
| 2300 | 2300 | ||
| 2301 | +/** | ||
| 2302 | + * @tc.name: SetDefaultFileSelectorShow001 | ||
| 2303 | + * @tc.desc: Test web_model_static.cpp | ||
| 2304 | + * @tc.type: FUNC | ||
| 2305 | + */ | ||
| 2306 | +HWTEST_F(WebModelStaticTest, SetDefaultFileSelectorShow001, TestSize.Level1) | ||
| 2307 | +{ | ||
| 2308 | + | ||
| 2309 | + int callCount = 0; | ||
| 2310 | + auto* stack = ViewStackProcessor::GetInstance(); | ||
| 2311 | + auto nodeId = stack->ClaimNodeId(); | ||
| 2312 | + auto frameNode = WebModelStatic::CreateFrameNode(nodeId); | ||
| 2313 | + ASSERT_NE(frameNode, nullptr); | ||
| 2314 | + stack->Push(frameNode); | ||
| 2315 | + auto callback = [&callCount](const BaseEventInfo* info) { | ||
| 2316 | + callCount++; | ||
| 2317 | + }; | ||
| 2318 | + WebModelStatic::SetDefaultFileSelectorShow(AccessibilityManager::RawPtr(frameNode), callback); | ||
| 2319 | + auto webPatternStatic = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<WebPatternStatic>(); | ||
| 2320 | + ASSERT_NE(webPatternStatic, nullptr); | ||
| 2321 | + | ||
| 2322 | + auto mockEventInfo = std::make_shared<MockBaseEventInfo>(); | ||
| 2323 | + webPatternStatic->GetDefaultFileSelectorShowCallback()(mockEventInfo); | ||
| 2324 | + EXPECT_NE(callCount, 0); | ||
| 2325 | + | ||
| 2326 | +} | ||
| 2327 | + | ||
| 2301 | /** | 2328 | /** |
| 2302 | * @tc.name: SetOnDetectedBlankScreen | 2329 | * @tc.name: SetOnDetectedBlankScreen |
| 2303 | * @tc.desc: Test web_model_static.cpp | 2330 | * @tc.desc: Test web_model_static.cpp |


release(paramPeer);release(resultPeer);