1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bridge/declarative_frontend/jsview/js_security_ui_extension.h"
17
18 #include <functional>
19 #include <string>
20 #include "want_params.h"
21
22 #include "base/log/ace_scoring_log.h"
23 #include "base/want/want_wrap.h"
24 #include "bridge/common/utils/engine_helper.h"
25 #include "bridge/declarative_frontend/engine/js_converter.h"
26 #include "bridge/declarative_frontend/jsview/js_utils.h"
27 #include "core/common/container_scope.h"
28 #include "core/components_ng/base/view_abstract_model.h"
29 #include "core/components_ng/base/view_stack_processor.h"
30 #include "core/components_ng/pattern/ui_extension/ui_extension_model.h"
31 #include "core/components_ng/pattern/ui_extension/ui_extension_model_ng.h"
32 #include "interfaces/include/ws_common.h"
33
34 namespace OHOS::Ace::Framework {
35 namespace {
36 constexpr int ARGC_TWO = 2;
37 const CalcDimension SECURITY_UEC_MIN_WIDTH(10.0f, DimensionUnit::VP);
38 const CalcDimension SECURITY_UEC_MIN_HEIGHT(10.0f, DimensionUnit::VP);
39 }
JSBind(BindingTarget globalObj)40 void JSSecurityUIExtensionProxy::JSBind(BindingTarget globalObj)
41 {
42 JSClass<JSSecurityUIExtensionProxy>::Declare("SecurityUIExtensionProxy");
43 JSClass<JSSecurityUIExtensionProxy>::CustomMethod("send", &JSSecurityUIExtensionProxy::Send);
44 JSClass<JSSecurityUIExtensionProxy>::CustomMethod("sendSync", &JSSecurityUIExtensionProxy::SendSync);
45 JSClass<JSSecurityUIExtensionProxy>::CustomMethod("on", &JSSecurityUIExtensionProxy::On);
46 JSClass<JSSecurityUIExtensionProxy>::CustomMethod("off", &JSSecurityUIExtensionProxy::Off);
47 JSClass<JSSecurityUIExtensionProxy>::Bind(
48 globalObj, &JSSecurityUIExtensionProxy::Constructor, &JSSecurityUIExtensionProxy::Destructor);
49 }
50
Constructor(const JSCallbackInfo & info)51 void JSSecurityUIExtensionProxy::Constructor(const JSCallbackInfo& info)
52 {
53 auto uiExtensionProxy = Referenced::MakeRefPtr<JSSecurityUIExtensionProxy>();
54 uiExtensionProxy->IncRefCount();
55 info.SetReturnValue(Referenced::RawPtr(uiExtensionProxy));
56 }
57
Destructor(JSSecurityUIExtensionProxy * uiExtensionProxy)58 void JSSecurityUIExtensionProxy::Destructor(JSSecurityUIExtensionProxy* uiExtensionProxy)
59 {
60 if (uiExtensionProxy != nullptr) {
61 uiExtensionProxy->DecRefCount();
62 }
63 }
64
Send(const JSCallbackInfo & info)65 void JSSecurityUIExtensionProxy::Send(const JSCallbackInfo& info)
66 {
67 if (!info[0]->IsObject()) {
68 return;
69 }
70 ContainerScope scope(instanceId_);
71 auto engine = EngineHelper::GetCurrentEngine();
72 CHECK_NULL_VOID(engine);
73 NativeEngine* nativeEngine = engine->GetNativeEngine();
74 panda::Local<JsiValue> value = info[0].Get().GetLocalHandle();
75 JSValueWrapper valueWrapper = value;
76 ScopeRAII scopeNapi(reinterpret_cast<napi_env>(nativeEngine));
77 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
78 auto wantParams = WantParamsWrap::CreateWantWrap(
79 reinterpret_cast<napi_env>(nativeEngine), nativeValue);
80 if (proxy_) {
81 proxy_->SendData(wantParams);
82 }
83 }
84
SendSync(const JSCallbackInfo & info)85 void JSSecurityUIExtensionProxy::SendSync(const JSCallbackInfo& info)
86 {
87 if (info.Length() == 0 || !info[0]->IsObject()) {
88 return;
89 }
90 ContainerScope scope(instanceId_);
91 auto engine = EngineHelper::GetCurrentEngine();
92 CHECK_NULL_VOID(engine);
93 NativeEngine* nativeEngine = engine->GetNativeEngine();
94 CHECK_NULL_VOID(nativeEngine);
95 panda::Local<JsiValue> value = info[0].Get().GetLocalHandle();
96 JSValueWrapper valueWrapper = value;
97 ScopeRAII scopeNapi(reinterpret_cast<napi_env>(nativeEngine));
98 napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
99 auto wantParams = WantParamsWrap::CreateWantWrap(
100 reinterpret_cast<napi_env>(nativeEngine), nativeValue);
101 if (proxy_) {
102 AAFwk::WantParams reWantParams;
103 int32_t sendCode = proxy_->SendDataSync(wantParams, reWantParams);
104 if (sendCode != 0) {
105 std::string errMsg;
106 if (sendCode == ERROR_CODE_UIEXTENSION_NOT_REGISTER_SYNC_CALLBACK) {
107 errMsg = "No callback has been registered to process synchronous data transferring.";
108 } else if (sendCode == ERROR_CODE_UIEXTENSION_TRANSFER_DATA_FAILED) {
109 errMsg = "Transferring data failed.";
110 } else {
111 errMsg = "Unknown error.";
112 }
113 JSException::Throw(sendCode, errMsg.c_str());
114 return;
115 }
116 auto execCtx = info.GetExecutionContext();
117 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
118 auto reNativeWantParams = WantWrap::ConvertParamsToNativeValue(
119 reWantParams, reinterpret_cast<napi_env>(nativeEngine));
120 auto reWantParamsJSVal =
121 Framework::JsConverter::ConvertNapiValueToJsVal(reNativeWantParams);
122 info.SetReturnValue(reWantParamsJSVal);
123 }
124 }
125
FindCbList(napi_env env,napi_value cb,SecurityCallbackFuncPairList & callbackFuncPairList)126 SecurityCallbackFuncPairList::const_iterator JSSecurityUIExtensionProxy::FindCbList(
127 napi_env env, napi_value cb, SecurityCallbackFuncPairList& callbackFuncPairList)
128 {
129 return std::find_if(callbackFuncPairList.begin(), callbackFuncPairList.end(),
130 [env, cb](const auto& item) -> bool {
131 bool result = false;
132 napi_value refItem;
133 napi_get_reference_value(env, item.first, &refItem);
134 napi_strict_equals(env, refItem, cb, &result);
135 return result;
136 });
137 }
138
AddCallbackToList(napi_env env,napi_value cb,napi_handle_scope scope,RegisterType type,const std::function<void (const RefPtr<NG::SecurityUIExtensionProxy> &)> && onFunc)139 void JSSecurityUIExtensionProxy::AddCallbackToList(
140 napi_env env, napi_value cb, napi_handle_scope scope, RegisterType type,
141 const std::function<void(const RefPtr<NG::SecurityUIExtensionProxy>&)>&& onFunc)
142 {
143 if (type == RegisterType::SYNC) {
144 auto iter = FindCbList(env, cb, onSyncOnCallbackList_);
145 if (iter == onSyncOnCallbackList_.end()) {
146 napi_ref ref = nullptr;
147 napi_create_reference(env, cb, 1, &ref);
148 onSyncOnCallbackList_.emplace_back(ref, onFunc);
149 }
150 } else if (type == RegisterType::ASYNC) {
151 auto iter = FindCbList(env, cb, onAsyncOnCallbackList_);
152 if (iter == onAsyncOnCallbackList_.end()) {
153 napi_ref ref = nullptr;
154 napi_create_reference(env, cb, 1, &ref);
155 onAsyncOnCallbackList_.emplace_back(ref, onFunc);
156 }
157 }
158 napi_close_handle_scope(env, scope);
159 }
160
DeleteCallbackFromList(int argc,napi_env env,napi_value cb,RegisterType type)161 void JSSecurityUIExtensionProxy::DeleteCallbackFromList(
162 int argc, napi_env env, napi_value cb, RegisterType type)
163 {
164 if (argc == 1) {
165 if (type == RegisterType::SYNC) {
166 for (const auto& item : onSyncOnCallbackList_) {
167 napi_delete_reference(env, item.first);
168 }
169 onSyncOnCallbackList_.clear();
170 } else if (type == RegisterType::ASYNC) {
171 for (const auto& item : onAsyncOnCallbackList_) {
172 napi_delete_reference(env, item.first);
173 }
174 onAsyncOnCallbackList_.clear();
175 }
176 } else if (argc == ARGC_TWO) {
177 if (type == RegisterType::SYNC) {
178 auto iter = FindCbList(env, cb, onSyncOnCallbackList_);
179 if (iter != onSyncOnCallbackList_.end()) {
180 napi_delete_reference(env, iter->first);
181 onSyncOnCallbackList_.erase(iter);
182 }
183 } else if (type == RegisterType::ASYNC) {
184 auto iter = FindCbList(env, cb, onAsyncOnCallbackList_);
185 if (iter != onAsyncOnCallbackList_.end()) {
186 napi_delete_reference(env, iter->first);
187 onAsyncOnCallbackList_.erase(iter);
188 }
189 }
190 }
191 }
192
GetOnFuncList(RegisterType type)193 std::list<std::function<void(const RefPtr<NG::SecurityUIExtensionProxy>&)>> JSSecurityUIExtensionProxy::GetOnFuncList(
194 RegisterType type)
195 {
196 std::list<std::function<void(const RefPtr<NG::SecurityUIExtensionProxy>&)>> reList;
197 if (type == RegisterType::SYNC) {
198 for (const auto& item : onSyncOnCallbackList_) {
199 reList.emplace_back(item.second);
200 }
201 } else if (type == RegisterType::ASYNC) {
202 for (const auto& item : onAsyncOnCallbackList_) {
203 reList.emplace_back(item.second);
204 }
205 }
206 return reList;
207 }
208
GetRegisterType(const std::string & strType)209 RegisterType JSSecurityUIExtensionProxy::GetRegisterType(const std::string& strType)
210 {
211 RegisterType type = RegisterType::UNKNOWN;
212 static constexpr char syncType[] = "syncReceiverRegister";
213 static constexpr char asyncType[] = "asyncReceiverRegister";
214 if (strType.compare(syncType) == 0) {
215 type = RegisterType::SYNC;
216 } else if (strType.compare(asyncType) == 0) {
217 type = RegisterType::ASYNC;
218 }
219 return type;
220 }
221
On(const JSCallbackInfo & info)222 void JSSecurityUIExtensionProxy::On(const JSCallbackInfo& info)
223 {
224 if (!info[0]->IsString() || !info[1]->IsFunction()) {
225 return;
226 }
227 const RegisterType registerType = GetRegisterType(info[0]->ToString());
228 if (registerType == RegisterType::UNKNOWN) {
229 return;
230 }
231
232 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(
233 NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
234 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
235 auto instanceId = ContainerScope::CurrentId();
236 auto onOnFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
237 instanceId, node = frameNode] (const RefPtr<NG::SecurityUIExtensionProxy>& session) {
238 ContainerScope scope(instanceId);
239 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
240 auto pipelineContext = PipelineContext::GetCurrentContext();
241 CHECK_NULL_VOID(pipelineContext);
242 pipelineContext->UpdateCurrentActiveNode(node);
243 JSRef<JSObject> contextObj = JSClass<JSSecurityUIExtensionProxy>::NewInstance();
244 RefPtr<JSSecurityUIExtensionProxy> proxy =
245 Referenced::Claim(contextObj->Unwrap<JSSecurityUIExtensionProxy>());
246 CHECK_NULL_VOID(proxy);
247 proxy->SetInstanceId(instanceId);
248 proxy->SetProxy(session);
249 auto param = JSRef<JSVal>::Cast(contextObj);
250 func->ExecuteJS(1, ¶m);
251 };
252
253 ContainerScope scope(instanceId_);
254 auto engine = EngineHelper::GetCurrentEngine();
255 CHECK_NULL_VOID(engine);
256 NativeEngine* nativeEngine = engine->GetNativeEngine();
257 CHECK_NULL_VOID(nativeEngine);
258 auto env = reinterpret_cast<napi_env>(nativeEngine);
259 ScopeRAII scopeNapi(env);
260 panda::Local<JsiValue> value = info[1].Get().GetLocalHandle();
261 JSValueWrapper valueWrapper = value;
262 napi_value cb = nativeEngine->ValueToNapiValue(valueWrapper);
263 napi_handle_scope napiScope = nullptr;
264 napi_open_handle_scope(env, &napiScope);
265 CHECK_NULL_VOID(napiScope);
266 std::lock_guard<std::mutex> lock(callbackLisLock_);
267 AddCallbackToList(env, cb, napiScope, registerType, std::move(onOnFunc));
268 auto pattern = proxy_->GetPattern();
269 CHECK_NULL_VOID(pattern);
270 auto onFuncList = GetOnFuncList(registerType);
271 if (registerType == RegisterType::SYNC) {
272 pattern->SetSyncCallbacks(std::move(onFuncList));
273 } else if (registerType == RegisterType::ASYNC) {
274 pattern->SetAsyncCallbacks(std::move(onFuncList));
275 }
276 }
277
Off(const JSCallbackInfo & info)278 void JSSecurityUIExtensionProxy::Off(const JSCallbackInfo& info)
279 {
280 if (!info[0]->IsString()) {
281 return;
282 }
283 const RegisterType registerType = GetRegisterType(info[0]->ToString());
284 if (registerType == RegisterType::UNKNOWN) {
285 return;
286 }
287
288 ContainerScope scope(instanceId_);
289 auto engine = EngineHelper::GetCurrentEngine();
290 CHECK_NULL_VOID(engine);
291 NativeEngine* nativeEngine = engine->GetNativeEngine();
292 CHECK_NULL_VOID(nativeEngine);
293 auto env = reinterpret_cast<napi_env>(nativeEngine);
294 ScopeRAII scopeNapi(env);
295 napi_value cb = nullptr;
296 if (info[1]->IsFunction()) {
297 panda::Local<JsiValue> value = info[1].Get().GetLocalHandle();
298 JSValueWrapper valueWrapper = value;
299 cb = nativeEngine->ValueToNapiValue(valueWrapper);
300 }
301
302 std::lock_guard<std::mutex> lock(callbackLisLock_);
303 DeleteCallbackFromList(info.Length(), env, cb, registerType);
304 auto pattern = proxy_->GetPattern();
305 CHECK_NULL_VOID(pattern);
306 auto onFuncList = GetOnFuncList(registerType);
307 if (registerType == RegisterType::SYNC) {
308 pattern->SetSyncCallbacks(std::move(onFuncList));
309 } else if (registerType == RegisterType::ASYNC) {
310 pattern->SetAsyncCallbacks(std::move(onFuncList));
311 }
312 }
313
SetInstanceId(int32_t instanceId)314 void JSSecurityUIExtensionProxy::SetInstanceId(int32_t instanceId)
315 {
316 instanceId_ = instanceId;
317 }
318
SetProxy(const RefPtr<NG::SecurityUIExtensionProxy> & proxy)319 void JSSecurityUIExtensionProxy::SetProxy(
320 const RefPtr<NG::SecurityUIExtensionProxy>& proxy)
321 {
322 proxy_ = proxy;
323 }
324
JSBind(BindingTarget globalObj)325 void JSSecurityUIExtension::JSBind(BindingTarget globalObj)
326 {
327 JSClass<JSSecurityUIExtension>::Declare("SecurityUIExtensionComponent");
328 MethodOptions opt = MethodOptions::NONE;
329 JSClass<JSSecurityUIExtension>::StaticMethod("create", &JSSecurityUIExtension::Create, opt);
330 JSClass<JSSecurityUIExtension>::StaticMethod("onRemoteReady", &JSSecurityUIExtension::OnRemoteReady);
331 JSClass<JSSecurityUIExtension>::StaticMethod("onReceive", &JSSecurityUIExtension::OnReceive);
332 JSClass<JSSecurityUIExtension>::StaticMethod("onError", &JSSecurityUIExtension::OnError);
333 JSClass<JSSecurityUIExtension>::StaticMethod("onTerminated", &JSSecurityUIExtension::OnTerminated);
334 JSClass<JSSecurityUIExtension>::StaticMethod("width", &JSViewAbstract::JsWidth);
335 JSClass<JSSecurityUIExtension>::StaticMethod("height", &JSViewAbstract::JsHeight);
336 JSClass<JSSecurityUIExtension>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
337 JSClass<JSSecurityUIExtension>::Bind(globalObj);
338 }
339
Create(const JSCallbackInfo & info)340 void JSSecurityUIExtension::Create(const JSCallbackInfo& info)
341 {
342 if (!info[0]->IsObject()) {
343 return;
344 }
345
346 NG::UIExtensionConfig config;
347 config.sessionType = NG::SessionType::SECURITY_UI_EXTENSION_ABILITY;
348 auto wantObj = JSRef<JSObject>::Cast(info[0]);
349 RefPtr<OHOS::Ace::WantWrap> want = CreateWantWrapFromNapiValue(wantObj);
350 if (want == nullptr) {
351 TAG_LOGI(AceLogTag::ACE_SECURITYUIEXTENSION, "want is nullptr");
352 return;
353 }
354
355 config.wantWrap = want;
356 RefPtr<NG::FrameNode> placeholderNode = nullptr;
357 if (info.Length() > 1 && info[1]->IsObject()) {
358 auto obj = JSRef<JSObject>::Cast(info[1]);
359 JSRef<JSVal> transferringCallerValue = obj->GetProperty("isTransferringCaller");
360 if (transferringCallerValue->IsBoolean()) {
361 config.transferringCaller = transferringCallerValue->ToBoolean();
362 }
363 JSRef<JSVal> enableDensityDPI = obj->GetProperty("dpiFollowStrategy");
364 if (enableDensityDPI->IsNumber()) {
365 config.densityDpi = (enableDensityDPI->ToNumber<int32_t>())==0 ? true : false;
366 }
367 do {
368 JSRef<JSVal> componentContent = obj->GetProperty("placeholder");
369 if (!componentContent->IsObject()) {
370 break;
371 }
372 auto componentContentObj = JSRef<JSObject>::Cast(componentContent);
373 JSRef<JSVal> builderNode = componentContentObj->GetProperty("builderNode_");
374 if (!builderNode->IsObject()) {
375 break;
376 }
377 auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
378 JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
379 if (nodePtr.IsEmpty()) {
380 break;
381 }
382 const auto* vm = nodePtr->GetEcmaVM();
383 auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
384 auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
385 if (!frameNode) {
386 break;
387 }
388 config.placeholderNode = AceType::Claim(frameNode);
389 } while (false);
390 }
391 UIExtensionModel::GetInstance()->Create(config);
392 ViewAbstractModel::GetInstance()->SetMinWidth(SECURITY_UEC_MIN_WIDTH);
393 ViewAbstractModel::GetInstance()->SetMinHeight(SECURITY_UEC_MIN_HEIGHT);
394 }
395
OnRemoteReady(const JSCallbackInfo & info)396 void JSSecurityUIExtension::OnRemoteReady(const JSCallbackInfo& info)
397 {
398 if (!info[0]->IsFunction()) {
399 return;
400 }
401 WeakPtr<NG::FrameNode> frameNode =
402 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
403 auto jsFunc = AceType::MakeRefPtr<JsFunction>(
404 JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
405 auto instanceId = ContainerScope::CurrentId();
406 auto onRemoteReady = [execCtx = info.GetExecutionContext(),
407 func = std::move(jsFunc), instanceId, node = frameNode]
408 (const RefPtr<NG::SecurityUIExtensionProxy>& session) {
409 ContainerScope scope(instanceId);
410 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
411 auto pipelineContext = PipelineContext::GetCurrentContext();
412 CHECK_NULL_VOID(pipelineContext);
413 pipelineContext->UpdateCurrentActiveNode(node);
414 JSRef<JSObject> contextObj = JSClass<JSSecurityUIExtensionProxy>::NewInstance();
415 RefPtr<JSSecurityUIExtensionProxy> proxy =
416 Referenced::Claim(contextObj->Unwrap<JSSecurityUIExtensionProxy>());
417 CHECK_NULL_VOID(proxy);
418 proxy->SetInstanceId(instanceId);
419 proxy->SetProxy(session);
420 auto returnValue = JSRef<JSVal>::Cast(contextObj);
421 func->ExecuteJS(1, &returnValue);
422 };
423 UIExtensionModel::GetInstance()->SetSecurityOnRemoteReady(std::move(onRemoteReady));
424 }
425
OnReceive(const JSCallbackInfo & info)426 void JSSecurityUIExtension::OnReceive(const JSCallbackInfo& info)
427 {
428 if (!info[0]->IsFunction()) {
429 return;
430 }
431 WeakPtr<NG::FrameNode> frameNode =
432 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
433 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
434 auto instanceId = ContainerScope::CurrentId();
435 auto onReceive = [execCtx = info.GetExecutionContext(),
436 func = std::move(jsFunc), instanceId, node = frameNode]
437 (const AAFwk::WantParams& wantParams) {
438 ContainerScope scope(instanceId);
439 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
440 ACE_SCORING_EVENT("SecurityUIExtensionComponent.UIExtensionDataSession.onReceive");
441 auto pipelineContext = PipelineContext::GetCurrentContext();
442 CHECK_NULL_VOID(pipelineContext);
443 pipelineContext->UpdateCurrentActiveNode(node);
444 auto engine = EngineHelper::GetCurrentEngine();
445 CHECK_NULL_VOID(engine);
446 NativeEngine* nativeEngine = engine->GetNativeEngine();
447 CHECK_NULL_VOID(nativeEngine);
448 auto env = reinterpret_cast<napi_env>(nativeEngine);
449 auto nativeWantParams = WantWrap::ConvertParamsToNativeValue(wantParams, env);
450 auto wantParamsJSVal = JsConverter::ConvertNapiValueToJsVal(nativeWantParams);
451 func->ExecuteJS(1, &wantParamsJSVal);
452 };
453 UIExtensionModel::GetInstance()->SetOnReceive(
454 std::move(onReceive), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
455 }
456
OnError(const JSCallbackInfo & info)457 void JSSecurityUIExtension::OnError(const JSCallbackInfo& info)
458 {
459 if (!info[0]->IsFunction()) {
460 return;
461 }
462 WeakPtr<NG::FrameNode> frameNode =
463 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
464 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
465 auto instanceId = ContainerScope::CurrentId();
466 auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
467 instanceId, node = frameNode] (int32_t code, const std::string& name, const std::string& message) {
468 ContainerScope scope(instanceId);
469 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
470 ACE_SCORING_EVENT("SecurityUIExtensionComponent.onError");
471 auto pipelineContext = PipelineContext::GetCurrentContext();
472 CHECK_NULL_VOID(pipelineContext);
473 pipelineContext->UpdateCurrentActiveNode(node);
474 JSRef<JSObject> obj = JSRef<JSObject>::New();
475 obj->SetProperty<int32_t>("code", code);
476 obj->SetProperty<std::string>("name", name);
477 obj->SetProperty<std::string>("message", message);
478 auto returnValue = JSRef<JSVal>::Cast(obj);
479 func->ExecuteJS(1, &returnValue);
480 };
481 UIExtensionModel::GetInstance()->SetOnError(
482 std::move(onError), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
483 }
484
OnTerminated(const JSCallbackInfo & info)485 void JSSecurityUIExtension::OnTerminated(const JSCallbackInfo& info)
486 {
487 if (!info[0]->IsFunction()) {
488 return;
489 }
490 WeakPtr<NG::FrameNode> frameNode =
491 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
492 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
493 auto instanceId = ContainerScope::CurrentId();
494 auto onTerminated = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
495 instanceId, node = frameNode] (int32_t code, const RefPtr<WantWrap>& wantWrap) {
496 ContainerScope scope(instanceId);
497 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
498 ACE_SCORING_EVENT("SecurityUIExtensionComponent.onTerminated");
499 auto pipelineContext = PipelineContext::GetCurrentContext();
500 CHECK_NULL_VOID(pipelineContext);
501 pipelineContext->UpdateCurrentActiveNode(node);
502 auto engine = EngineHelper::GetCurrentEngine();
503 CHECK_NULL_VOID(engine);
504 NativeEngine* nativeEngine = engine->GetNativeEngine();
505 CHECK_NULL_VOID(nativeEngine);
506 JSRef<JSObject> obj = JSRef<JSObject>::New();
507 obj->SetProperty<int32_t>("code", code);
508 if (wantWrap) {
509 auto nativeWant = WantWrap::ConvertToNativeValue(
510 wantWrap->GetWant(), reinterpret_cast<napi_env>(nativeEngine));
511 auto wantJSVal = JsConverter::ConvertNapiValueToJsVal(nativeWant);
512 obj->SetPropertyObject("want", wantJSVal);
513 }
514 auto returnValue = JSRef<JSVal>::Cast(obj);
515 func->ExecuteJS(1, &returnValue);
516 };
517 UIExtensionModel::GetInstance()->SetOnTerminated(
518 std::move(onTerminated), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
519 }
520 } // namespace OHOS::Ace::Framework
521