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 uint8_t 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(uint32_t argc,napi_env env,napi_value cb,RegisterType type)161 void JSSecurityUIExtensionProxy::DeleteCallbackFromList(
162 uint32_t 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
NeedCheckComponentSize()222 bool NeedCheckComponentSize()
223 {
224 std::string type =
225 UIExtensionModel::GetInstance()->GetUiExtensionType(NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
226 if (type.empty()) {
227 return true;
228 }
229 const std::unordered_set<std::string> noNeedCheckExtensionType = { "sysPicker/photoPicker" };
230 return noNeedCheckExtensionType.find(type) == noNeedCheckExtensionType.end();
231 }
232
CreateInstanceAndSet(NG::UIExtensionConfig & config)233 void CreateInstanceAndSet(NG::UIExtensionConfig& config)
234 {
235 UIExtensionModel::GetInstance()->Create(config);
236 ViewAbstractModel::GetInstance()->SetMinWidth(SECURITY_UEC_MIN_WIDTH);
237 ViewAbstractModel::GetInstance()->SetMinHeight(SECURITY_UEC_MIN_HEIGHT);
238 if (!NeedCheckComponentSize()) {
239 LOGI("No need check size due to extension type is special");
240 return;
241 }
242 ViewAbstractModel::GetInstance()->SetWidth(SECURITY_UEC_MIN_WIDTH);
243 ViewAbstractModel::GetInstance()->SetHeight(SECURITY_UEC_MIN_HEIGHT);
244 }
245
CanTurnOn(const JSCallbackInfo & info)246 bool JSSecurityUIExtensionProxy::CanTurnOn(const JSCallbackInfo& info)
247 {
248 if (!info[0]->IsString() || !info[1]->IsFunction()) {
249 return false;
250 }
251 const RegisterType registerType = GetRegisterType(info[0]->ToString());
252 return registerType != RegisterType::UNKNOWN;
253 }
254
On(const JSCallbackInfo & info)255 void JSSecurityUIExtensionProxy::On(const JSCallbackInfo& info)
256 {
257 if (!CanTurnOn(info)) {
258 return;
259 }
260 const RegisterType registerType = GetRegisterType(info[0]->ToString());
261 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(
262 NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
263 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
264 auto instanceId = ContainerScope::CurrentId();
265 auto onOnFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
266 instanceId, node = frameNode] (const RefPtr<NG::SecurityUIExtensionProxy>& session) {
267 ContainerScope scope(instanceId);
268 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
269 auto pipelineContext = PipelineContext::GetCurrentContext();
270 CHECK_NULL_VOID(pipelineContext);
271 pipelineContext->UpdateCurrentActiveNode(node);
272 JSRef<JSObject> contextObj = JSClass<JSSecurityUIExtensionProxy>::NewInstance();
273 RefPtr<JSSecurityUIExtensionProxy> proxy =
274 Referenced::Claim(contextObj->Unwrap<JSSecurityUIExtensionProxy>());
275 CHECK_NULL_VOID(proxy);
276 proxy->SetInstanceId(instanceId);
277 proxy->SetProxy(session);
278 auto param = JSRef<JSVal>::Cast(contextObj);
279 func->ExecuteJS(1, ¶m);
280 };
281
282 ContainerScope scope(instanceId_);
283 auto engine = EngineHelper::GetCurrentEngine();
284 CHECK_NULL_VOID(engine);
285 NativeEngine* nativeEngine = engine->GetNativeEngine();
286 CHECK_NULL_VOID(nativeEngine);
287 auto env = reinterpret_cast<napi_env>(nativeEngine);
288 ScopeRAII scopeNapi(env);
289 panda::Local<JsiValue> value = info[1].Get().GetLocalHandle();
290 JSValueWrapper valueWrapper = value;
291 napi_value cb = nativeEngine->ValueToNapiValue(valueWrapper);
292 napi_handle_scope napiScope = nullptr;
293 napi_open_handle_scope(env, &napiScope);
294 CHECK_NULL_VOID(napiScope);
295 std::lock_guard<std::mutex> lock(callbackLisLock_);
296 AddCallbackToList(env, cb, napiScope, registerType, std::move(onOnFunc));
297 auto pattern = proxy_->GetPattern();
298 CHECK_NULL_VOID(pattern);
299 auto onFuncList = GetOnFuncList(registerType);
300 if (registerType == RegisterType::SYNC) {
301 pattern->SetSyncCallbacks(std::move(onFuncList));
302 } else if (registerType == RegisterType::ASYNC) {
303 pattern->SetAsyncCallbacks(std::move(onFuncList));
304 }
305 }
306
Off(const JSCallbackInfo & info)307 void JSSecurityUIExtensionProxy::Off(const JSCallbackInfo& info)
308 {
309 if (!info[0]->IsString()) {
310 return;
311 }
312 const RegisterType registerType = GetRegisterType(info[0]->ToString());
313 if (registerType == RegisterType::UNKNOWN) {
314 return;
315 }
316
317 ContainerScope scope(instanceId_);
318 auto engine = EngineHelper::GetCurrentEngine();
319 CHECK_NULL_VOID(engine);
320 NativeEngine* nativeEngine = engine->GetNativeEngine();
321 CHECK_NULL_VOID(nativeEngine);
322 auto env = reinterpret_cast<napi_env>(nativeEngine);
323 ScopeRAII scopeNapi(env);
324 napi_value cb = nullptr;
325 if (info[1]->IsFunction()) {
326 panda::Local<JsiValue> value = info[1].Get().GetLocalHandle();
327 JSValueWrapper valueWrapper = value;
328 cb = nativeEngine->ValueToNapiValue(valueWrapper);
329 }
330
331 std::lock_guard<std::mutex> lock(callbackLisLock_);
332 DeleteCallbackFromList(info.Length(), env, cb, registerType);
333 auto pattern = proxy_->GetPattern();
334 CHECK_NULL_VOID(pattern);
335 auto onFuncList = GetOnFuncList(registerType);
336 if (registerType == RegisterType::SYNC) {
337 pattern->SetSyncCallbacks(std::move(onFuncList));
338 } else if (registerType == RegisterType::ASYNC) {
339 pattern->SetAsyncCallbacks(std::move(onFuncList));
340 }
341 }
342
SetInstanceId(int32_t instanceId)343 void JSSecurityUIExtensionProxy::SetInstanceId(int32_t instanceId)
344 {
345 instanceId_ = instanceId;
346 }
347
SetProxy(const RefPtr<NG::SecurityUIExtensionProxy> & proxy)348 void JSSecurityUIExtensionProxy::SetProxy(
349 const RefPtr<NG::SecurityUIExtensionProxy>& proxy)
350 {
351 proxy_ = proxy;
352 }
353
JSBind(BindingTarget globalObj)354 void JSSecurityUIExtension::JSBind(BindingTarget globalObj)
355 {
356 JSClass<JSSecurityUIExtension>::Declare("SecurityUIExtensionComponent");
357 MethodOptions opt = MethodOptions::NONE;
358 JSClass<JSSecurityUIExtension>::StaticMethod("create", &JSSecurityUIExtension::Create, opt);
359 JSClass<JSSecurityUIExtension>::StaticMethod("onRemoteReady", &JSSecurityUIExtension::OnRemoteReady);
360 JSClass<JSSecurityUIExtension>::StaticMethod("onReceive", &JSSecurityUIExtension::OnReceive);
361 JSClass<JSSecurityUIExtension>::StaticMethod("onError", &JSSecurityUIExtension::OnError);
362 JSClass<JSSecurityUIExtension>::StaticMethod("onTerminated", &JSSecurityUIExtension::OnTerminated);
363 JSClass<JSSecurityUIExtension>::StaticMethod("width", &JSSecurityUIExtension::JsWidth);
364 JSClass<JSSecurityUIExtension>::StaticMethod("height", &JSSecurityUIExtension::JsHeight);
365 JSClass<JSSecurityUIExtension>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
366 JSClass<JSSecurityUIExtension>::Bind(globalObj);
367 }
368
GetSizeValue(const JSCallbackInfo & info)369 CalcDimension JSSecurityUIExtension::GetSizeValue(const JSCallbackInfo& info)
370 {
371 CalcDimension value;
372 if (!JSViewAbstract::ParseJsDimensionVp(info[0], value)) {
373 return -1.0;
374 }
375 return value;
376 }
377
JsWidth(const JSCallbackInfo & info)378 void JSSecurityUIExtension::JsWidth(const JSCallbackInfo& info)
379 {
380 CalcDimension value = GetSizeValue(info);
381 if (NeedCheckComponentSize() && LessNotEqual(value.Value(), 0.0)) {
382 return;
383 }
384 JSViewAbstract::JsWidth(info);
385 }
386
JsHeight(const JSCallbackInfo & info)387 void JSSecurityUIExtension::JsHeight(const JSCallbackInfo& info)
388 {
389 CalcDimension value = GetSizeValue(info);
390 if (NeedCheckComponentSize() && LessNotEqual(value.Value(), 0.0)) {
391 return;
392 }
393 JSViewAbstract::JsHeight(info);
394 }
395
Create(const JSCallbackInfo & info)396 void JSSecurityUIExtension::Create(const JSCallbackInfo& info)
397 {
398 if (!info[0]->IsObject()) {
399 return;
400 }
401
402 NG::UIExtensionConfig config;
403 config.sessionType = NG::SessionType::SECURITY_UI_EXTENSION_ABILITY;
404 auto wantObj = JSRef<JSObject>::Cast(info[0]);
405 RefPtr<OHOS::Ace::WantWrap> want = CreateWantWrapFromNapiValue(wantObj);
406 if (want == nullptr) {
407 TAG_LOGI(AceLogTag::ACE_SECURITYUIEXTENSION, "want is nullptr");
408 return;
409 }
410
411 config.wantWrap = want;
412 RefPtr<NG::FrameNode> placeholderNode = nullptr;
413 if (info.Length() > 1 && info[1]->IsObject()) {
414 auto obj = JSRef<JSObject>::Cast(info[1]);
415 JSRef<JSVal> transferringCallerValue = obj->GetProperty("isTransferringCaller");
416 if (transferringCallerValue->IsBoolean()) {
417 config.transferringCaller = transferringCallerValue->ToBoolean();
418 }
419 JSRef<JSVal> enableDensityDPI = obj->GetProperty("dpiFollowStrategy");
420 if (enableDensityDPI->IsNumber()) {
421 config.densityDpi = (enableDensityDPI->ToNumber<int32_t>())==0 ? true : false;
422 }
423 do {
424 JSRef<JSVal> componentContent = obj->GetProperty("placeholder");
425 if (!componentContent->IsObject()) {
426 break;
427 }
428 auto componentContentObj = JSRef<JSObject>::Cast(componentContent);
429 JSRef<JSVal> builderNode = componentContentObj->GetProperty("builderNode_");
430 if (!builderNode->IsObject()) {
431 break;
432 }
433 auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
434 JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
435 if (nodePtr.IsEmpty()) {
436 break;
437 }
438 const auto* vm = nodePtr->GetEcmaVM();
439 auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
440 auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
441 if (!frameNode) {
442 break;
443 }
444 config.placeholderNode = AceType::Claim(frameNode);
445 } while (false);
446 }
447 CreateInstanceAndSet(config);
448 }
449
OnRemoteReady(const JSCallbackInfo & info)450 void JSSecurityUIExtension::OnRemoteReady(const JSCallbackInfo& info)
451 {
452 if (!info[0]->IsFunction()) {
453 return;
454 }
455 WeakPtr<NG::FrameNode> frameNode =
456 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
457 auto jsFunc = AceType::MakeRefPtr<JsFunction>(
458 JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
459 auto instanceId = ContainerScope::CurrentId();
460 auto onRemoteReady = [execCtx = info.GetExecutionContext(),
461 func = std::move(jsFunc), instanceId, node = frameNode]
462 (const RefPtr<NG::SecurityUIExtensionProxy>& session) {
463 ContainerScope scope(instanceId);
464 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
465 auto pipelineContext = PipelineContext::GetCurrentContext();
466 CHECK_NULL_VOID(pipelineContext);
467 pipelineContext->UpdateCurrentActiveNode(node);
468 JSRef<JSObject> contextObj = JSClass<JSSecurityUIExtensionProxy>::NewInstance();
469 RefPtr<JSSecurityUIExtensionProxy> proxy =
470 Referenced::Claim(contextObj->Unwrap<JSSecurityUIExtensionProxy>());
471 CHECK_NULL_VOID(proxy);
472 proxy->SetInstanceId(instanceId);
473 proxy->SetProxy(session);
474 auto returnValue = JSRef<JSVal>::Cast(contextObj);
475 func->ExecuteJS(1, &returnValue);
476 };
477 UIExtensionModel::GetInstance()->SetSecurityOnRemoteReady(std::move(onRemoteReady));
478 }
479
OnReceive(const JSCallbackInfo & info)480 void JSSecurityUIExtension::OnReceive(const JSCallbackInfo& info)
481 {
482 if (!info[0]->IsFunction()) {
483 return;
484 }
485 WeakPtr<NG::FrameNode> frameNode =
486 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
487 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
488 auto instanceId = ContainerScope::CurrentId();
489 auto onReceive = [execCtx = info.GetExecutionContext(),
490 func = std::move(jsFunc), instanceId, node = frameNode]
491 (const AAFwk::WantParams& wantParams) {
492 ContainerScope scope(instanceId);
493 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
494 ACE_SCORING_EVENT("SecurityUIExtensionComponent.UIExtensionDataSession.onReceive");
495 auto pipelineContext = PipelineContext::GetCurrentContext();
496 CHECK_NULL_VOID(pipelineContext);
497 pipelineContext->UpdateCurrentActiveNode(node);
498 auto engine = EngineHelper::GetCurrentEngine();
499 CHECK_NULL_VOID(engine);
500 NativeEngine* nativeEngine = engine->GetNativeEngine();
501 CHECK_NULL_VOID(nativeEngine);
502 auto env = reinterpret_cast<napi_env>(nativeEngine);
503 auto nativeWantParams = WantWrap::ConvertParamsToNativeValue(wantParams, env);
504 auto wantParamsJSVal = JsConverter::ConvertNapiValueToJsVal(nativeWantParams);
505 func->ExecuteJS(1, &wantParamsJSVal);
506 };
507 UIExtensionModel::GetInstance()->SetOnReceive(
508 std::move(onReceive), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
509 }
510
OnError(const JSCallbackInfo & info)511 void JSSecurityUIExtension::OnError(const JSCallbackInfo& info)
512 {
513 if (!info[0]->IsFunction()) {
514 return;
515 }
516 WeakPtr<NG::FrameNode> frameNode =
517 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
518 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
519 auto instanceId = ContainerScope::CurrentId();
520 auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
521 instanceId, node = frameNode] (int32_t code, const std::string& name, const std::string& message) {
522 ContainerScope scope(instanceId);
523 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
524 ACE_SCORING_EVENT("SecurityUIExtensionComponent.onError");
525 auto pipelineContext = PipelineContext::GetCurrentContext();
526 CHECK_NULL_VOID(pipelineContext);
527 pipelineContext->UpdateCurrentActiveNode(node);
528 JSRef<JSObject> obj = JSRef<JSObject>::New();
529 obj->SetProperty<int32_t>("code", code);
530 obj->SetProperty<std::string>("name", name);
531 obj->SetProperty<std::string>("message", message);
532 auto returnValue = JSRef<JSVal>::Cast(obj);
533 func->ExecuteJS(1, &returnValue);
534 };
535 UIExtensionModel::GetInstance()->SetOnError(
536 std::move(onError), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
537 }
538
OnTerminated(const JSCallbackInfo & info)539 void JSSecurityUIExtension::OnTerminated(const JSCallbackInfo& info)
540 {
541 if (!info[0]->IsFunction()) {
542 return;
543 }
544 WeakPtr<NG::FrameNode> frameNode =
545 AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
546 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
547 auto instanceId = ContainerScope::CurrentId();
548 auto onTerminated = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
549 instanceId, node = frameNode] (int32_t code, const RefPtr<WantWrap>& wantWrap) {
550 ContainerScope scope(instanceId);
551 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
552 ACE_SCORING_EVENT("SecurityUIExtensionComponent.onTerminated");
553 auto pipelineContext = PipelineContext::GetCurrentContext();
554 CHECK_NULL_VOID(pipelineContext);
555 pipelineContext->UpdateCurrentActiveNode(node);
556 auto engine = EngineHelper::GetCurrentEngine();
557 CHECK_NULL_VOID(engine);
558 NativeEngine* nativeEngine = engine->GetNativeEngine();
559 CHECK_NULL_VOID(nativeEngine);
560 JSRef<JSObject> obj = JSRef<JSObject>::New();
561 obj->SetProperty<int32_t>("code", code);
562 if (wantWrap) {
563 auto nativeWant = WantWrap::ConvertToNativeValue(
564 wantWrap->GetWant(), reinterpret_cast<napi_env>(nativeEngine));
565 auto wantJSVal = JsConverter::ConvertNapiValueToJsVal(nativeWant);
566 obj->SetPropertyObject("want", wantJSVal);
567 }
568 auto returnValue = JSRef<JSVal>::Cast(obj);
569 func->ExecuteJS(1, &returnValue);
570 };
571 UIExtensionModel::GetInstance()->SetOnTerminated(
572 std::move(onTerminated), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
573 }
574 } // namespace OHOS::Ace::Framework
575