• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/preview_ui_extension_component/preview_ui_extension_adapter.h"
31 #include "core/components_ng/pattern/ui_extension/ui_extension_model.h"
32 #include "core/components_ng/pattern/ui_extension/ui_extension_model_ng.h"
33 #include "interfaces/include/ws_common.h"
34 
35 namespace OHOS::Ace::Framework {
36 namespace {
37     constexpr uint8_t ARGC_TWO = 2;
38     const CalcDimension SECURITY_UEC_MIN_WIDTH(10.0f, DimensionUnit::VP);
39     const CalcDimension SECURITY_UEC_MIN_HEIGHT(10.0f, DimensionUnit::VP);
40 }
JSBind(BindingTarget globalObj)41 void JSSecurityUIExtensionProxy::JSBind(BindingTarget globalObj)
42 {
43     JSClass<JSSecurityUIExtensionProxy>::Declare("SecurityUIExtensionProxy");
44     JSClass<JSSecurityUIExtensionProxy>::CustomMethod("send", &JSSecurityUIExtensionProxy::Send);
45     JSClass<JSSecurityUIExtensionProxy>::CustomMethod("sendSync", &JSSecurityUIExtensionProxy::SendSync);
46     JSClass<JSSecurityUIExtensionProxy>::CustomMethod("on", &JSSecurityUIExtensionProxy::On);
47     JSClass<JSSecurityUIExtensionProxy>::CustomMethod("off", &JSSecurityUIExtensionProxy::Off);
48     JSClass<JSSecurityUIExtensionProxy>::Bind(
49         globalObj, &JSSecurityUIExtensionProxy::Constructor, &JSSecurityUIExtensionProxy::Destructor);
50 }
51 
Constructor(const JSCallbackInfo & info)52 void JSSecurityUIExtensionProxy::Constructor(const JSCallbackInfo& info)
53 {
54     auto uiExtensionProxy = Referenced::MakeRefPtr<JSSecurityUIExtensionProxy>();
55     uiExtensionProxy->IncRefCount();
56     info.SetReturnValue(Referenced::RawPtr(uiExtensionProxy));
57 }
58 
Destructor(JSSecurityUIExtensionProxy * uiExtensionProxy)59 void JSSecurityUIExtensionProxy::Destructor(JSSecurityUIExtensionProxy* uiExtensionProxy)
60 {
61     if (uiExtensionProxy != nullptr) {
62         uiExtensionProxy->DecRefCount();
63     }
64 }
65 
Send(const JSCallbackInfo & info)66 void JSSecurityUIExtensionProxy::Send(const JSCallbackInfo& info)
67 {
68     if (!info[0]->IsObject()) {
69         return;
70     }
71     ContainerScope scope(instanceId_);
72     auto engine = EngineHelper::GetCurrentEngine();
73     CHECK_NULL_VOID(engine);
74     NativeEngine* nativeEngine = engine->GetNativeEngine();
75     panda::Local<JsiValue> value = info[0].Get().GetLocalHandle();
76     JSValueWrapper valueWrapper = value;
77     ScopeRAII scopeNapi(reinterpret_cast<napi_env>(nativeEngine));
78     napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
79     auto wantParams = WantParamsWrap::CreateWantWrap(
80         reinterpret_cast<napi_env>(nativeEngine), nativeValue);
81     if (proxy_) {
82         proxy_->SendData(wantParams);
83     }
84 }
85 
SendSync(const JSCallbackInfo & info)86 void JSSecurityUIExtensionProxy::SendSync(const JSCallbackInfo& info)
87 {
88     if (info.Length() == 0 || !info[0]->IsObject()) {
89         return;
90     }
91     ContainerScope scope(instanceId_);
92     auto engine = EngineHelper::GetCurrentEngine();
93     CHECK_NULL_VOID(engine);
94     NativeEngine* nativeEngine = engine->GetNativeEngine();
95     CHECK_NULL_VOID(nativeEngine);
96     panda::Local<JsiValue> value = info[0].Get().GetLocalHandle();
97     JSValueWrapper valueWrapper = value;
98     ScopeRAII scopeNapi(reinterpret_cast<napi_env>(nativeEngine));
99     napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
100     auto wantParams = WantParamsWrap::CreateWantWrap(
101         reinterpret_cast<napi_env>(nativeEngine), nativeValue);
102     if (proxy_) {
103         AAFwk::WantParams reWantParams;
104         int32_t sendCode = proxy_->SendDataSync(wantParams, reWantParams);
105         if (sendCode != 0) {
106             std::string errMsg;
107             if (sendCode == ERROR_CODE_UIEXTENSION_NOT_REGISTER_SYNC_CALLBACK) {
108                 errMsg = "No callback has been registered to process synchronous data transferring.";
109             } else if (sendCode == ERROR_CODE_UIEXTENSION_TRANSFER_DATA_FAILED) {
110                 errMsg = "Transferring data failed.";
111             } else {
112                 errMsg = "Unknown error.";
113             }
114             JSException::Throw(sendCode, errMsg.c_str());
115             return;
116         }
117         auto execCtx = info.GetExecutionContext();
118         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
119         auto reNativeWantParams = WantWrap::ConvertParamsToNativeValue(
120             reWantParams, reinterpret_cast<napi_env>(nativeEngine));
121         auto reWantParamsJSVal =
122             Framework::JsConverter::ConvertNapiValueToJsVal(reNativeWantParams);
123         info.SetReturnValue(reWantParamsJSVal);
124     }
125 }
126 
FindCbList(napi_env env,napi_value cb,SecurityCallbackFuncPairList & callbackFuncPairList)127 SecurityCallbackFuncPairList::const_iterator JSSecurityUIExtensionProxy::FindCbList(
128     napi_env env, napi_value cb, SecurityCallbackFuncPairList& callbackFuncPairList)
129 {
130     return std::find_if(callbackFuncPairList.begin(), callbackFuncPairList.end(),
131         [env, cb](const auto& item) -> bool {
132         bool result = false;
133         napi_value refItem;
134         napi_get_reference_value(env, item.first, &refItem);
135         napi_strict_equals(env, refItem, cb, &result);
136         return result;
137     });
138 }
139 
AddCallbackToList(napi_env env,napi_value cb,napi_handle_scope scope,RegisterType type,const std::function<void (const RefPtr<NG::SecurityUIExtensionProxy> &)> && onFunc)140 void JSSecurityUIExtensionProxy::AddCallbackToList(
141     napi_env env, napi_value cb, napi_handle_scope scope, RegisterType type,
142     const std::function<void(const RefPtr<NG::SecurityUIExtensionProxy>&)>&& onFunc)
143 {
144     if (type == RegisterType::SYNC) {
145         auto iter = FindCbList(env, cb, onSyncOnCallbackList_);
146         if (iter == onSyncOnCallbackList_.end()) {
147             napi_ref ref = nullptr;
148             napi_create_reference(env, cb, 1, &ref);
149             onSyncOnCallbackList_.emplace_back(ref, onFunc);
150         }
151     } else if (type == RegisterType::ASYNC) {
152         auto iter = FindCbList(env, cb, onAsyncOnCallbackList_);
153         if (iter == onAsyncOnCallbackList_.end()) {
154             napi_ref ref = nullptr;
155             napi_create_reference(env, cb, 1, &ref);
156             onAsyncOnCallbackList_.emplace_back(ref, onFunc);
157         }
158     }
159     napi_close_handle_scope(env, scope);
160 }
161 
DeleteCallbackFromList(uint32_t argc,napi_env env,napi_value cb,RegisterType type)162 void JSSecurityUIExtensionProxy::DeleteCallbackFromList(
163     uint32_t argc, napi_env env, napi_value cb, RegisterType type)
164 {
165     if (argc == 1) {
166         if (type == RegisterType::SYNC) {
167             for (const auto& item : onSyncOnCallbackList_) {
168                 napi_delete_reference(env, item.first);
169             }
170             onSyncOnCallbackList_.clear();
171         } else if (type == RegisterType::ASYNC) {
172             for (const auto& item : onAsyncOnCallbackList_) {
173                 napi_delete_reference(env, item.first);
174             }
175             onAsyncOnCallbackList_.clear();
176         }
177     } else if (argc == ARGC_TWO) {
178         if (type == RegisterType::SYNC) {
179             auto iter = FindCbList(env, cb, onSyncOnCallbackList_);
180             if (iter != onSyncOnCallbackList_.end()) {
181                 napi_delete_reference(env, iter->first);
182                 onSyncOnCallbackList_.erase(iter);
183             }
184         } else if (type == RegisterType::ASYNC) {
185             auto iter = FindCbList(env, cb, onAsyncOnCallbackList_);
186             if (iter != onAsyncOnCallbackList_.end()) {
187                 napi_delete_reference(env, iter->first);
188                 onAsyncOnCallbackList_.erase(iter);
189             }
190         }
191     }
192 }
193 
GetOnFuncList(RegisterType type)194 std::list<std::function<void(const RefPtr<NG::SecurityUIExtensionProxy>&)>> JSSecurityUIExtensionProxy::GetOnFuncList(
195     RegisterType type)
196 {
197     std::list<std::function<void(const RefPtr<NG::SecurityUIExtensionProxy>&)>> reList;
198     if (type == RegisterType::SYNC) {
199         for (const auto& item : onSyncOnCallbackList_) {
200             reList.emplace_back(item.second);
201         }
202     } else if (type == RegisterType::ASYNC) {
203         for (const auto& item : onAsyncOnCallbackList_) {
204             reList.emplace_back(item.second);
205         }
206     }
207     return reList;
208 }
209 
GetRegisterType(const std::string & strType)210 RegisterType JSSecurityUIExtensionProxy::GetRegisterType(const std::string& strType)
211 {
212     RegisterType type = RegisterType::UNKNOWN;
213     static constexpr char syncType[] = "syncReceiverRegister";
214     static constexpr char asyncType[] = "asyncReceiverRegister";
215     if (strType.compare(syncType) == 0) {
216         type = RegisterType::SYNC;
217     } else if (strType.compare(asyncType) == 0) {
218         type = RegisterType::ASYNC;
219     }
220     return type;
221 }
222 
NeedCheckComponentSize()223 bool NeedCheckComponentSize()
224 {
225     std::string type =
226         UIExtensionModel::GetInstance()->GetUiExtensionType(NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
227     if (type.empty()) {
228         return true;
229     }
230     const std::unordered_set<std::string> noNeedCheckExtensionType = { "sysPicker/photoPicker" };
231     return noNeedCheckExtensionType.find(type) == noNeedCheckExtensionType.end();
232 }
233 
CreateInstanceAndSet(NG::UIExtensionConfig & config)234 void CreateInstanceAndSet(NG::UIExtensionConfig& config)
235 {
236     UIExtensionModel::GetInstance()->Create(config);
237     ViewAbstractModel::GetInstance()->SetMinWidth(SECURITY_UEC_MIN_WIDTH);
238     ViewAbstractModel::GetInstance()->SetMinHeight(SECURITY_UEC_MIN_HEIGHT);
239     if (!NeedCheckComponentSize()) {
240         LOGI("No need check size due to extension type is special");
241         return;
242     }
243     ViewAbstractModel::GetInstance()->SetWidth(SECURITY_UEC_MIN_WIDTH);
244     ViewAbstractModel::GetInstance()->SetHeight(SECURITY_UEC_MIN_HEIGHT);
245 }
246 
CanTurnOn(const JSCallbackInfo & info)247 bool JSSecurityUIExtensionProxy::CanTurnOn(const JSCallbackInfo& info)
248 {
249     if (!info[0]->IsString() || !info[1]->IsFunction()) {
250         return false;
251     }
252     const RegisterType registerType = GetRegisterType(info[0]->ToString());
253     return registerType != RegisterType::UNKNOWN;
254 }
255 
On(const JSCallbackInfo & info)256 void JSSecurityUIExtensionProxy::On(const JSCallbackInfo& info)
257 {
258     if (!CanTurnOn(info)) {
259         return;
260     }
261     const RegisterType registerType = GetRegisterType(info[0]->ToString());
262     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(
263         NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
264     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
265     auto instanceId = ContainerScope::CurrentId();
266     auto onOnFunc = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
267         instanceId, node = frameNode] (const RefPtr<NG::SecurityUIExtensionProxy>& session) {
268             ContainerScope scope(instanceId);
269             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
270             auto pipelineContext = PipelineContext::GetCurrentContext();
271             CHECK_NULL_VOID(pipelineContext);
272             pipelineContext->UpdateCurrentActiveNode(node);
273             JSRef<JSObject> contextObj = JSClass<JSSecurityUIExtensionProxy>::NewInstance();
274             RefPtr<JSSecurityUIExtensionProxy> proxy =
275                 Referenced::Claim(contextObj->Unwrap<JSSecurityUIExtensionProxy>());
276             CHECK_NULL_VOID(proxy);
277             proxy->SetInstanceId(instanceId);
278             proxy->SetProxy(session);
279             auto param = JSRef<JSVal>::Cast(contextObj);
280             func->ExecuteJS(1, &param);
281         };
282 
283     ContainerScope scope(instanceId_);
284     auto engine = EngineHelper::GetCurrentEngine();
285     CHECK_NULL_VOID(engine);
286     NativeEngine* nativeEngine = engine->GetNativeEngine();
287     CHECK_NULL_VOID(nativeEngine);
288     auto env = reinterpret_cast<napi_env>(nativeEngine);
289     ScopeRAII scopeNapi(env);
290     panda::Local<JsiValue> value = info[1].Get().GetLocalHandle();
291     JSValueWrapper valueWrapper = value;
292     napi_value cb = nativeEngine->ValueToNapiValue(valueWrapper);
293     napi_handle_scope napiScope = nullptr;
294     napi_open_handle_scope(env, &napiScope);
295     CHECK_NULL_VOID(napiScope);
296     std::lock_guard<std::mutex> lock(callbackLisLock_);
297     AddCallbackToList(env, cb, napiScope, registerType, std::move(onOnFunc));
298     auto pattern = proxy_->GetPattern();
299     CHECK_NULL_VOID(pattern);
300     auto onFuncList = GetOnFuncList(registerType);
301     if (registerType == RegisterType::SYNC) {
302         pattern->SetSyncCallbacks(std::move(onFuncList));
303     } else if (registerType == RegisterType::ASYNC) {
304         pattern->SetAsyncCallbacks(std::move(onFuncList));
305     }
306 }
307 
Off(const JSCallbackInfo & info)308 void JSSecurityUIExtensionProxy::Off(const JSCallbackInfo& info)
309 {
310     if (!info[0]->IsString()) {
311         return;
312     }
313     const RegisterType registerType = GetRegisterType(info[0]->ToString());
314     if (registerType == RegisterType::UNKNOWN) {
315         return;
316     }
317 
318     ContainerScope scope(instanceId_);
319     auto engine = EngineHelper::GetCurrentEngine();
320     CHECK_NULL_VOID(engine);
321     NativeEngine* nativeEngine = engine->GetNativeEngine();
322     CHECK_NULL_VOID(nativeEngine);
323     auto env = reinterpret_cast<napi_env>(nativeEngine);
324     ScopeRAII scopeNapi(env);
325     napi_value cb = nullptr;
326     if (info[1]->IsFunction()) {
327         panda::Local<JsiValue> value = info[1].Get().GetLocalHandle();
328         JSValueWrapper valueWrapper = value;
329         cb = nativeEngine->ValueToNapiValue(valueWrapper);
330     }
331 
332     std::lock_guard<std::mutex> lock(callbackLisLock_);
333     DeleteCallbackFromList(info.Length(), env, cb, registerType);
334     auto pattern = proxy_->GetPattern();
335     CHECK_NULL_VOID(pattern);
336     auto onFuncList = GetOnFuncList(registerType);
337     if (registerType == RegisterType::SYNC) {
338         pattern->SetSyncCallbacks(std::move(onFuncList));
339     } else if (registerType == RegisterType::ASYNC) {
340         pattern->SetAsyncCallbacks(std::move(onFuncList));
341     }
342 }
343 
SetInstanceId(int32_t instanceId)344 void JSSecurityUIExtensionProxy::SetInstanceId(int32_t instanceId)
345 {
346     instanceId_ = instanceId;
347 }
348 
SetProxy(const RefPtr<NG::SecurityUIExtensionProxy> & proxy)349 void JSSecurityUIExtensionProxy::SetProxy(
350     const RefPtr<NG::SecurityUIExtensionProxy>& proxy)
351 {
352     proxy_ = proxy;
353 }
354 
JSBind(BindingTarget globalObj)355 void JSSecurityUIExtension::JSBind(BindingTarget globalObj)
356 {
357     JSClass<JSSecurityUIExtension>::Declare("SecurityUIExtensionComponent");
358     MethodOptions opt = MethodOptions::NONE;
359     JSClass<JSSecurityUIExtension>::StaticMethod("create", &JSSecurityUIExtension::Create, opt);
360     JSClass<JSSecurityUIExtension>::StaticMethod("onRemoteReady", &JSSecurityUIExtension::OnRemoteReady);
361     JSClass<JSSecurityUIExtension>::StaticMethod("onReceive", &JSSecurityUIExtension::OnReceive);
362     JSClass<JSSecurityUIExtension>::StaticMethod("onError", &JSSecurityUIExtension::OnError);
363     JSClass<JSSecurityUIExtension>::StaticMethod("onTerminated", &JSSecurityUIExtension::OnTerminated);
364     JSClass<JSSecurityUIExtension>::StaticMethod("width", &JSSecurityUIExtension::JsWidth);
365     JSClass<JSSecurityUIExtension>::StaticMethod("height", &JSSecurityUIExtension::JsHeight);
366     JSClass<JSSecurityUIExtension>::StaticMethod("backgroundColor", &JSViewAbstract::JsBackgroundColor);
367     JSClass<JSSecurityUIExtension>::Bind(globalObj);
368 }
369 
GetSizeValue(const JSCallbackInfo & info)370 CalcDimension JSSecurityUIExtension::GetSizeValue(const JSCallbackInfo& info)
371 {
372     CalcDimension value;
373     if (!JSViewAbstract::ParseJsDimensionVp(info[0], value)) {
374         return -1.0;
375     }
376     return value;
377 }
378 
JsWidth(const JSCallbackInfo & info)379 void JSSecurityUIExtension::JsWidth(const JSCallbackInfo& info)
380 {
381     CalcDimension value = GetSizeValue(info);
382     if (NeedCheckComponentSize() && LessNotEqual(value.Value(), 0.0)) {
383         return;
384     }
385     JSViewAbstract::JsWidth(info);
386 }
387 
JsHeight(const JSCallbackInfo & info)388 void JSSecurityUIExtension::JsHeight(const JSCallbackInfo& info)
389 {
390     CalcDimension value = GetSizeValue(info);
391     if (NeedCheckComponentSize() && LessNotEqual(value.Value(), 0.0)) {
392         return;
393     }
394     JSViewAbstract::JsHeight(info);
395 }
396 
Create(const JSCallbackInfo & info)397 void JSSecurityUIExtension::Create(const JSCallbackInfo& info)
398 {
399     if (!info[0]->IsObject()) {
400         return;
401     }
402 
403     NG::UIExtensionConfig config;
404     config.sessionType = NG::SessionType::SECURITY_UI_EXTENSION_ABILITY;
405     auto wantObj = JSRef<JSObject>::Cast(info[0]);
406     RefPtr<OHOS::Ace::WantWrap> want = CreateWantWrapFromNapiValue(wantObj);
407     if (want == nullptr) {
408         TAG_LOGI(AceLogTag::ACE_SECURITYUIEXTENSION, "want is nullptr");
409         return;
410     }
411 
412     config.wantWrap = want;
413     RefPtr<NG::FrameNode> placeholderNode = nullptr;
414     if (info.Length() > 1 && info[1]->IsObject()) {
415         auto obj = JSRef<JSObject>::Cast(info[1]);
416         JSRef<JSVal> transferringCallerValue = obj->GetProperty("isTransferringCaller");
417         if (transferringCallerValue->IsBoolean()) {
418             config.transferringCaller = transferringCallerValue->ToBoolean();
419         }
420         JSRef<JSVal> enableDensityDPI = obj->GetProperty("dpiFollowStrategy");
421         if (enableDensityDPI->IsNumber()) {
422             config.densityDpi = (enableDensityDPI->ToNumber<int32_t>())==0 ? true : false;
423         }
424         do {
425             JSRef<JSVal> componentContent = obj->GetProperty("placeholder");
426             if (!componentContent->IsObject()) {
427                 break;
428             }
429             auto componentContentObj = JSRef<JSObject>::Cast(componentContent);
430             JSRef<JSVal> builderNode = componentContentObj->GetProperty("builderNode_");
431             if (!builderNode->IsObject()) {
432                 break;
433             }
434             auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
435             JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
436             if (nodePtr.IsEmpty()) {
437                 break;
438             }
439             const auto* vm = nodePtr->GetEcmaVM();
440             auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
441             auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
442             if (!frameNode) {
443                 break;
444             }
445             config.placeholderNode = AceType::Claim(frameNode);
446         } while (false);
447     }
448     CreateInstanceAndSet(config);
449 }
450 
OnRemoteReady(const JSCallbackInfo & info)451 void JSSecurityUIExtension::OnRemoteReady(const JSCallbackInfo& info)
452 {
453     if (!info[0]->IsFunction()) {
454         return;
455     }
456     WeakPtr<NG::FrameNode> frameNode =
457         AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
458     auto jsFunc = AceType::MakeRefPtr<JsFunction>(
459         JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
460     auto instanceId = ContainerScope::CurrentId();
461     auto onRemoteReady = [execCtx = info.GetExecutionContext(),
462         func = std::move(jsFunc), instanceId, node = frameNode]
463             (const RefPtr<NG::SecurityUIExtensionProxy>& session) {
464             ContainerScope scope(instanceId);
465             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
466             auto pipelineContext = PipelineContext::GetCurrentContext();
467             CHECK_NULL_VOID(pipelineContext);
468             pipelineContext->UpdateCurrentActiveNode(node);
469             JSRef<JSObject> contextObj = JSClass<JSSecurityUIExtensionProxy>::NewInstance();
470             RefPtr<JSSecurityUIExtensionProxy> proxy =
471                 Referenced::Claim(contextObj->Unwrap<JSSecurityUIExtensionProxy>());
472             CHECK_NULL_VOID(proxy);
473             proxy->SetInstanceId(instanceId);
474             proxy->SetProxy(session);
475             auto returnValue = JSRef<JSVal>::Cast(contextObj);
476             func->ExecuteJS(1, &returnValue);
477         };
478     UIExtensionModel::GetInstance()->SetSecurityOnRemoteReady(std::move(onRemoteReady));
479 }
480 
OnReceive(const JSCallbackInfo & info)481 void JSSecurityUIExtension::OnReceive(const JSCallbackInfo& info)
482 {
483     if (!info[0]->IsFunction()) {
484         return;
485     }
486     WeakPtr<NG::FrameNode> frameNode =
487         AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
488     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
489     auto instanceId = ContainerScope::CurrentId();
490     auto onReceive = [execCtx = info.GetExecutionContext(),
491         func = std::move(jsFunc), instanceId, node = frameNode]
492             (const AAFwk::WantParams& wantParams) {
493             ContainerScope scope(instanceId);
494             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
495             ACE_SCORING_EVENT("SecurityUIExtensionComponent.UIExtensionDataSession.onReceive");
496             auto pipelineContext = PipelineContext::GetCurrentContext();
497             CHECK_NULL_VOID(pipelineContext);
498             pipelineContext->UpdateCurrentActiveNode(node);
499             auto engine = EngineHelper::GetCurrentEngine();
500             CHECK_NULL_VOID(engine);
501             NativeEngine* nativeEngine = engine->GetNativeEngine();
502             CHECK_NULL_VOID(nativeEngine);
503             auto env = reinterpret_cast<napi_env>(nativeEngine);
504             auto nativeWantParams = WantWrap::ConvertParamsToNativeValue(wantParams, env);
505             auto wantParamsJSVal = JsConverter::ConvertNapiValueToJsVal(nativeWantParams);
506             func->ExecuteJS(1, &wantParamsJSVal);
507         };
508     UIExtensionModel::GetInstance()->SetOnReceive(
509         std::move(onReceive), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
510 }
511 
OnError(const JSCallbackInfo & info)512 void JSSecurityUIExtension::OnError(const JSCallbackInfo& info)
513 {
514     if (!info[0]->IsFunction()) {
515         return;
516     }
517     WeakPtr<NG::FrameNode> frameNode =
518         AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
519     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
520     auto instanceId = ContainerScope::CurrentId();
521     auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
522         instanceId, node = frameNode] (int32_t code, const std::string& name, const std::string& message) {
523             ContainerScope scope(instanceId);
524             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
525             ACE_SCORING_EVENT("SecurityUIExtensionComponent.onError");
526             auto pipelineContext = PipelineContext::GetCurrentContext();
527             CHECK_NULL_VOID(pipelineContext);
528             pipelineContext->UpdateCurrentActiveNode(node);
529             JSRef<JSObject> obj = JSRef<JSObject>::New();
530             obj->SetProperty<int32_t>("code", code);
531             obj->SetProperty<std::string>("name", name);
532             obj->SetProperty<std::string>("message", message);
533             auto returnValue = JSRef<JSVal>::Cast(obj);
534             func->ExecuteJS(1, &returnValue);
535         };
536     UIExtensionModel::GetInstance()->SetOnError(
537         std::move(onError), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
538 }
539 
OnTerminated(const JSCallbackInfo & info)540 void JSSecurityUIExtension::OnTerminated(const JSCallbackInfo& info)
541 {
542     if (!info[0]->IsFunction()) {
543         return;
544     }
545     WeakPtr<NG::FrameNode> frameNode =
546         AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
547     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
548     auto instanceId = ContainerScope::CurrentId();
549     auto onTerminated = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
550         instanceId, node = frameNode] (int32_t code, const RefPtr<WantWrap>& wantWrap) {
551             ContainerScope scope(instanceId);
552             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
553             ACE_SCORING_EVENT("SecurityUIExtensionComponent.onTerminated");
554             auto pipelineContext = PipelineContext::GetCurrentContext();
555             CHECK_NULL_VOID(pipelineContext);
556             pipelineContext->UpdateCurrentActiveNode(node);
557             auto engine = EngineHelper::GetCurrentEngine();
558             CHECK_NULL_VOID(engine);
559             NativeEngine* nativeEngine = engine->GetNativeEngine();
560             CHECK_NULL_VOID(nativeEngine);
561             JSRef<JSObject> obj = JSRef<JSObject>::New();
562             obj->SetProperty<int32_t>("code", code);
563             if (wantWrap) {
564                 auto nativeWant = WantWrap::ConvertToNativeValue(
565                     wantWrap->GetWant(), reinterpret_cast<napi_env>(nativeEngine));
566                 auto wantJSVal = JsConverter::ConvertNapiValueToJsVal(nativeWant);
567                 obj->SetPropertyObject("want", wantJSVal);
568             }
569             auto returnValue = JSRef<JSVal>::Cast(obj);
570             func->ExecuteJS(1, &returnValue);
571         };
572     UIExtensionModel::GetInstance()->SetOnTerminated(
573         std::move(onTerminated), NG::SessionType::SECURITY_UI_EXTENSION_ABILITY);
574 }
575 
JSBind(BindingTarget globalObj)576 void JSPreviewUIExtension::JSBind(BindingTarget globalObj)
577 {
578     JSClass<JSPreviewUIExtension>::Declare("PreviewUIExtensionComponent");
579     MethodOptions opt = MethodOptions::NONE;
580     JSClass<JSPreviewUIExtension>::StaticMethod("create", &JSPreviewUIExtension::Create, opt);
581     JSClass<JSPreviewUIExtension>::StaticMethod("onError", &JSPreviewUIExtension::OnError);
582     JSClass<JSPreviewUIExtension>::StaticMethod("width", &JSPreviewUIExtension::JsWidth);
583     JSClass<JSPreviewUIExtension>::StaticMethod("height", &JSPreviewUIExtension::JsHeight);
584     JSClass<JSPreviewUIExtension>::Bind(globalObj);
585 }
586 
GetSizeValue(const JSCallbackInfo & info)587 static CalcDimension GetSizeValue(const JSCallbackInfo& info)
588 {
589     CalcDimension value;
590     if (!JSViewAbstract::ParseJsDimensionVp(info[0], value)) {
591         return -1.0;
592     }
593     return value;
594 }
595 
JsWidth(const JSCallbackInfo & info)596 void JSPreviewUIExtension::JsWidth(const JSCallbackInfo& info)
597 {
598     JSViewAbstract::JsWidth(info);
599     CalcDimension value = GetSizeValue(info);
600     if (LessNotEqual(value.Value(), 0.0)) {
601         return;
602     }
603     ViewAbstractModel::GetInstance()->SetWidth(value);
604 }
605 
JsHeight(const JSCallbackInfo & info)606 void JSPreviewUIExtension::JsHeight(const JSCallbackInfo& info)
607 {
608     JSViewAbstract::JsHeight(info);
609     CalcDimension value = GetSizeValue(info);
610     if (LessNotEqual(value.Value(), 0.0)) {
611         return;
612     }
613     ViewAbstractModel::GetInstance()->SetHeight(value);
614 }
615 
Create(const JSCallbackInfo & info)616 void JSPreviewUIExtension::Create(const JSCallbackInfo& info)
617 {
618     if (!info[0]->IsObject()) {
619         return;
620     }
621     NG::UIExtensionConfig config;
622     config.sessionType = NG::SessionType::UI_EXTENSION_ABILITY;
623     auto wantObj = JSRef<JSObject>::Cast(info[0]);
624     RefPtr<OHOS::Ace::WantWrap> want = CreateWantWrapFromNapiValue(wantObj);
625     if (want == nullptr) {
626         TAG_LOGI(AceLogTag::ACE_SECURITYUIEXTENSION, "want is nullptr");
627         return;
628     }
629     config.wantWrap = want;
630     RefPtr<NG::FrameNode> placeholderNode = nullptr;
631     if (info.Length() > 1 && info[1]->IsObject()) {
632         auto obj = JSRef<JSObject>::Cast(info[1]);
633         JSRef<JSVal> transferringCallerValue = obj->GetProperty("isTransferringCaller");
634         if (transferringCallerValue->IsBoolean()) {
635             config.transferringCaller = transferringCallerValue->ToBoolean();
636         }
637         JSRef<JSVal> enableDensityDPI = obj->GetProperty("dpiFollowStrategy");
638         if (enableDensityDPI->IsNumber()) {
639             config.densityDpi = (enableDensityDPI->ToNumber<int32_t>())==0 ? true : false;
640         }
641         do {
642             JSRef<JSVal> componentContent = obj->GetProperty("placeholder");
643             if (!componentContent->IsObject()) {
644                 break;
645             }
646             auto componentContentObj = JSRef<JSObject>::Cast(componentContent);
647             JSRef<JSVal> builderNode = componentContentObj->GetProperty("builderNode_");
648             if (!builderNode->IsObject()) {
649                 break;
650             }
651             auto builderNodeObj = JSRef<JSObject>::Cast(builderNode);
652             JSRef<JSVal> nodePtr = builderNodeObj->GetProperty("nodePtr_");
653             if (nodePtr.IsEmpty()) {
654                 break;
655             }
656             const auto* vm = nodePtr->GetEcmaVM();
657             auto* node = nodePtr->GetLocalHandle()->ToNativePointer(vm)->Value();
658             auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
659             if (!frameNode) {
660                 break;
661             }
662             config.placeholderNode = AceType::Claim(frameNode);
663         } while (false);
664     }
665     NG::PreviewUIExtensionAdapter::GetInstance()->Create(config);
666 }
667 
OnError(const JSCallbackInfo & info)668 void JSPreviewUIExtension::OnError(const JSCallbackInfo& info)
669 {
670     if (!info[0]->IsFunction()) {
671         return;
672     }
673     auto frameNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
674     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
675     auto instanceId = ContainerScope::CurrentId();
676     auto onError = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
677         instanceId, node = AceType::WeakClaim(frameNode)]
678         (int32_t code, const std::string& name, const std::string& message) {
679             ContainerScope scope(instanceId);
680             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
681             ACE_SCORING_EVENT("PreviewUIExtensionComponent.onError");
682             auto pipelineContext = PipelineContext::GetCurrentContext();
683             CHECK_NULL_VOID(pipelineContext);
684             pipelineContext->UpdateCurrentActiveNode(node);
685             JSRef<JSObject> obj = JSRef<JSObject>::New();
686             obj->SetProperty<int32_t>("code", code);
687             obj->SetProperty<std::string>("name", name);
688             obj->SetProperty<std::string>("message", message);
689             auto returnValue = JSRef<JSVal>::Cast(obj);
690             func->ExecuteJS(1, &returnValue);
691         };
692     NG::PreviewUIExtensionAdapter::GetInstance()->SetOnError(AceType::Claim(frameNode), std::move(onError));
693 }
694 } // namespace OHOS::Ace::Framework
695