1 /*
2 * Copyright (c) 2021-2022 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 "frameworks/bridge/js_frontend/engine/jsi/jsi_engine.h"
17
18 #ifndef WINDOWS_PLATFORM
19 #include <dlfcn.h>
20 #endif
21 #include <regex>
22 #include <unistd.h>
23
24 #include "base/i18n/localization.h"
25 #include "base/log/ace_trace.h"
26 #include "base/log/event_report.h"
27 #include "base/thread/task_executor.h"
28 #include "base/utils/time_util.h"
29 #include "bridge/js_frontend/engine/jsi/ark_js_runtime.h"
30 #include "bridge/js_frontend/engine/jsi/ark_js_value.h"
31 #include "bridge/js_frontend/engine/jsi/jsi_base_utils.h"
32 #include "core/common/ace_application_info.h"
33 #include "core/common/connect_server_manager.h"
34 #include "core/common/container.h"
35 #include "core/common/container_scope.h"
36 #include "core/components/common/layout/grid_system_manager.h"
37 #include "frameworks/bridge/common/utils/utils.h"
38 #include "frameworks/bridge/js_frontend/engine/common/js_api_perf.h"
39 #include "frameworks/bridge/js_frontend/engine/common/js_constants.h"
40 #include "frameworks/bridge/js_frontend/engine/common/runtime_constants.h"
41 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_animation_bridge.h"
42 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_animator_bridge.h"
43 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_badge_bridge.h"
44 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_canvas_bridge.h"
45 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_chart_bridge.h"
46 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_clock_bridge.h"
47 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_component_api_bridge.h"
48 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_image_animator_bridge.h"
49 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_input_bridge.h"
50 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_list_bridge.h"
51 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_offscreen_canvas_bridge.h"
52 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_stepper_bridge.h"
53 #include "frameworks/bridge/js_frontend/engine/jsi/jsi_xcomponent_bridge.h"
54
55 #ifdef PIXEL_MAP_SUPPORTED
56 #include "pixel_map.h"
57 #include "pixel_map_napi.h"
58 #endif
59
60 #ifndef OHOS_PALTFORM
61 extern const char _binary_strip_native_min_abc_start[];
62 extern const char _binary_strip_native_min_abc_end[];
63 #endif
64
65 namespace OHOS::Ace::Framework {
66
67 const int SYSTEM_BASE = 10;
68
69 #if defined(ANDROID_PLATFORM)
70 const std::string ARK_DEBUGGER_LIB_PATH = "libark_debugger.so";
71 #elif defined(APP_USE_ARM)
72 const std::string ARK_DEBUGGER_LIB_PATH = "/system/lib/libark_debugger.z.so";
73 #else
74 const std::string ARK_DEBUGGER_LIB_PATH = "/system/lib64/libark_debugger.z.so";
75 #endif
76 const int32_t MAX_READ_TEXT_LENGTH = 4096;
77 const std::regex URI_PATTERN("^\\/([a-z0-9A-Z_]+\\/)*[a-z0-9A-Z_]+\\.?[a-z0-9A-Z_]*$");
78 using std::shared_ptr;
79 static int32_t globalNodeId = 100000;
80 std::map<const std::string, std::string> JsiEngineInstance::dataMap_;
81 RefPtr<Clipboard> clipboard;
82
83 #if !defined(PREVIEW)
CreatePixelMapFromNapiValue(const shared_ptr<JsRuntime> & runtime,shared_ptr<JsValue> jsValue)84 RefPtr<PixelMap> CreatePixelMapFromNapiValue(const shared_ptr<JsRuntime>& runtime, shared_ptr<JsValue> jsValue)
85 {
86 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
87 if (!engine) {
88 LOGE("engine is null.");
89 return nullptr;
90 }
91
92 auto nativeEngine = static_cast<ArkNativeEngine*>(engine->GetNativeEngine());
93 if (!nativeEngine) {
94 LOGE("NativeEngine is null");
95 return nullptr;
96 }
97
98 shared_ptr<ArkJSValue> arkJsValue = std::static_pointer_cast<ArkJSValue>(jsValue);
99 if (!arkJsValue) {
100 LOGE("arkJsValue is null.");
101 return nullptr;
102 }
103 shared_ptr<ArkJSRuntime> arkRuntime = std::static_pointer_cast<ArkJSRuntime>(runtime);
104 if (!arkRuntime) {
105 LOGE("arkRuntime is null");
106 return nullptr;
107 }
108
109 JSValueWrapper valueWrapper = arkJsValue->GetValue(arkRuntime);
110 NativeValue* nativeValue = nativeEngine->ValueToNativeValue(valueWrapper);
111
112 PixelMapNapiEntry pixelMapNapiEntry = JsEngine::GetPixelMapNapiEntry();
113 if (!pixelMapNapiEntry) {
114 LOGE("pixelMapNapiEntry is null");
115 return nullptr;
116 }
117 void* pixmapPtrAddr =
118 pixelMapNapiEntry(reinterpret_cast<napi_env>(nativeEngine), reinterpret_cast<napi_value>(nativeValue));
119 if (pixmapPtrAddr == nullptr) {
120 LOGE(" Failed to get pixmap pointer");
121 return nullptr;
122 }
123 return PixelMap::CreatePixelMap(pixmapPtrAddr);
124 }
125 #endif
126
GetStagingPage(const shared_ptr<JsRuntime> & runtime)127 RefPtr<JsAcePage> GetStagingPage(const shared_ptr<JsRuntime>& runtime)
128 {
129 LOGD("GetStagingPage");
130 if (!runtime) {
131 LOGE("JsRuntime is null, cannot get staging page!");
132 return nullptr;
133 }
134 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
135 return engineInstance->GetStagingPage();
136 }
137
GetRunningPage(const shared_ptr<JsRuntime> & runtime)138 RefPtr<JsAcePage> GetRunningPage(const shared_ptr<JsRuntime>& runtime)
139 {
140 LOGD("GetRunningPage");
141 if (!runtime) {
142 LOGE("JsRuntime is null, cannot get running page!");
143 return nullptr;
144 }
145 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
146 return engineInstance->GetRunningPage();
147 }
148
GetFrontendDelegate(const shared_ptr<JsRuntime> & runtime)149 RefPtr<FrontendDelegate> GetFrontendDelegate(const shared_ptr<JsRuntime>& runtime)
150 {
151 LOGD("GetFrontendDelegate");
152 if (!runtime) {
153 LOGE("JsRuntime is null, cannot get frontend delegate!");
154 return nullptr;
155 }
156 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
157 return engineInstance->GetFrontendDelegate();
158 }
159
GetValueAsString(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & value,std::string & str)160 void GetValueAsString(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& value, std::string& str)
161 {
162 if (!value->IsObject(runtime)) {
163 LOGE("JsValue is not an object!");
164 return;
165 }
166 int32_t len = 0;
167 shared_ptr<JsValue> propertyNames;
168 value->GetEnumerablePropertyNames(runtime, propertyNames, len);
169 for (int32_t i = 0; i < len; ++i) {
170 if (i != 0) {
171 str.append(1, DOM_PICKER_SPLIT_ARRAY);
172 }
173
174 shared_ptr<JsValue> key = propertyNames->GetElement(runtime, i);
175 shared_ptr<JsValue> item = value->GetProperty(runtime, key);
176
177 if (item->IsString(runtime) || item->IsNumber(runtime) || item->IsBoolean(runtime)) {
178 std::string valStr = item->ToString(runtime);
179 str.append(valStr);
180 continue;
181 }
182 if (item->IsArray(runtime)) {
183 int32_t subLen = item->GetArrayLength(runtime);
184 for (int32_t j = 0; j < subLen; ++j) {
185 if (j != 0) {
186 str.append(1, DOM_PICKER_SPLIT_ITEM);
187 }
188
189 shared_ptr<JsValue> subItem = item->GetElement(runtime, j);
190 std::string subItemStr = subItem->ToString(runtime);
191 str.append(subItemStr);
192 }
193 continue;
194 }
195 }
196 }
197
GetStyleFamilyValue(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & value,std::string & familyStyle)198 void GetStyleFamilyValue(
199 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& value, std::string& familyStyle)
200 {
201 std::string family;
202 std::string src;
203 int32_t len = value->GetArrayLength(runtime);
204 for (int32_t i = 0; i < len; ++i) {
205 // ValArray is one row of family array
206 shared_ptr<JsValue> element = value->GetElement(runtime, i);
207 if (element->IsObject(runtime)) {
208 shared_ptr<JsValue> properties;
209 int32_t objLen = 0;
210 element->GetPropertyNames(runtime, properties, objLen);
211 for (int32_t j = 0; j < objLen; ++j) {
212 shared_ptr<JsValue> propKey = properties->GetElement(runtime, j);
213 shared_ptr<JsValue> propValue = element->GetProperty(runtime, propKey);
214 if (propValue->IsString(runtime)) {
215 std::string propValueStr = propValue->ToString(runtime);
216 std::string propKeyStr = propKey->ToString(runtime);
217 if (propKeyStr == "fontFamily") {
218 family = propValueStr;
219 if (!src.empty()) {
220 GetFrontendDelegate(runtime)->RegisterFont(family, src);
221 family.erase();
222 src.erase();
223 }
224 if (familyStyle.length() > 0) {
225 familyStyle += ",";
226 }
227 familyStyle += propValueStr;
228 } else if (propKeyStr == "src") {
229 // The format of font src is: url("src"), here get the src.
230 src = propValueStr.substr(URL_SOURCE_START_IDX, propValueStr.length() - URL_SOURCE_SUFFIX_LEN);
231 if (!family.empty()) {
232 GetFrontendDelegate(runtime)->RegisterFont(family, src);
233 family.erase();
234 src.erase();
235 }
236 }
237 }
238 }
239 }
240 }
241 }
242
GetStyleAnimationName(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & value,std::vector<std::unordered_map<std::string,std::string>> & styleVec)243 void GetStyleAnimationName(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& value,
244 std::vector<std::unordered_map<std::string, std::string>>& styleVec)
245 {
246 int32_t len = value->GetArrayLength(runtime);
247 for (int32_t i = 0; i < len; ++i) {
248 std::unordered_map<std::string, std::string> animationNameKeyFrame;
249 shared_ptr<JsValue> element = value->GetElement(runtime, i);
250 if (element->IsObject(runtime)) {
251 int32_t objLen = 0;
252 shared_ptr<JsValue> properties;
253 element->GetPropertyNames(runtime, properties, objLen);
254 for (int32_t j = 0; j < objLen; ++j) {
255 shared_ptr<JsValue> propKey = properties->GetElement(runtime, j);
256 shared_ptr<JsValue> propValue = element->GetProperty(runtime, propKey);
257 if (propValue->IsString(runtime) || propValue->IsNumber(runtime)) {
258 std::string propKeyStr = propKey->ToString(runtime);
259 std::string propValueStr = propValue->ToString(runtime);
260 animationNameKeyFrame.emplace(propKeyStr, propValueStr);
261 } else {
262 LOGD("GetStyleAnimationName: type of value is either string nor object, unsupported.");
263 }
264 }
265 }
266 if (!animationNameKeyFrame.empty()) {
267 styleVec.emplace_back(animationNameKeyFrame);
268 }
269 }
270 }
271
GetAttrImage(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & valObject,ImageProperties & imageProperties)272 void GetAttrImage(
273 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& valObject, ImageProperties& imageProperties)
274 {
275 if (!runtime || !valObject) {
276 return;
277 }
278 shared_ptr<JsValue> propertyNames;
279 int32_t len = 0;
280 valObject->GetPropertyNames(runtime, propertyNames, len);
281 for (auto i = 0; i < len; ++i) {
282 shared_ptr<JsValue> key = propertyNames->GetElement(runtime, i);
283 if (!key) {
284 LOGW("key is null. Ignoring!");
285 continue;
286 }
287 std::string keyStr = key->ToString(runtime);
288 shared_ptr<JsValue> value = valObject->GetProperty(runtime, key);
289 if (!value) {
290 LOGW("value is null. Ignoring!");
291 continue;
292 }
293 std::string valStr = value->ToString(runtime);
294 if (value->IsString(runtime) || value->IsNumber(runtime) || value->IsBoolean(runtime)) {
295 if (keyStr == DOM_SRC) {
296 imageProperties.src = valStr;
297 } else if (keyStr == DOM_WIDTH) {
298 imageProperties.width = StringToDimension(valStr);
299 } else if (keyStr == DOM_HEIGHT) {
300 imageProperties.height = StringToDimension(valStr);
301 } else if (keyStr == DOM_TOP) {
302 imageProperties.top = StringToDimension(valStr);
303 } else if (keyStr == DOM_LEFT) {
304 imageProperties.left = StringToDimension(valStr);
305 } else if (keyStr == DOM_DURATION) {
306 imageProperties.duration = StringToInt(valStr);
307 } else {
308 LOGD("key : %{public}s unsupported. Ignoring!", keyStr.c_str());
309 }
310 } else {
311 LOGD("value of unsupported type. Ignoring!");
312 }
313 }
314 }
315
GetAttrImages(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arrayVal,std::vector<ImageProperties> & images)316 void GetAttrImages(
317 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arrayVal, std::vector<ImageProperties>& images)
318 {
319 if (!arrayVal) {
320 return;
321 }
322 int32_t length = arrayVal->GetArrayLength(runtime);
323 for (int32_t i = 0; i < length; ++i) {
324 shared_ptr<JsValue> valArray = arrayVal->GetProperty(runtime, i);
325 ImageProperties imageProperties;
326 if (valArray && valArray->IsObject(runtime)) {
327 GetAttrImage(runtime, valArray, imageProperties);
328 images.push_back(imageProperties);
329 }
330 }
331 }
332
SetDomAttributesWithArray(const shared_ptr<JsRuntime> & runtime,const std::string & keyStr,const shared_ptr<JsValue> & value,std::vector<std::pair<std::string,std::string>> & attrs,JsCommandDomElementOperator & command)333 void SetDomAttributesWithArray(const shared_ptr<JsRuntime>& runtime, const std::string& keyStr,
334 const shared_ptr<JsValue>& value, std::vector<std::pair<std::string, std::string>>& attrs,
335 JsCommandDomElementOperator& command)
336 {
337 if (!value->IsArray(runtime)) {
338 LOGE("Value is not array type.");
339 return;
340 }
341 if (keyStr == "datasets") {
342 auto chartBridge = AceType::MakeRefPtr<JsiChartBridge>();
343 chartBridge->GetAttrDatasets(runtime, value);
344 command.SetDatasets(chartBridge->GetDatasets());
345 } else if (keyStr == "images") {
346 std::vector<ImageProperties> images;
347 GetAttrImages(runtime, value, images);
348 command.SetImagesAttr(std::move(images));
349 } else if (keyStr == "segments") {
350 auto chartBridge = AceType::MakeRefPtr<JsiChartBridge>();
351 chartBridge->ParseAttrSegmentArray(runtime, value);
352 command.SetSegments(chartBridge->GetSegments());
353 } else if (keyStr == "menuoptions") {
354 auto inputBridge = AceType::MakeRefPtr<JsiInputBridge>();
355 inputBridge->ParseInputOptions(runtime, value);
356 command.SetInputOptions(inputBridge->GetInputOptions());
357 } else {
358 std::string valStr;
359 GetValueAsString(runtime, value, valStr);
360 LOGD("SetDomAttributes: key: %{private}s, attr: %{private}s", keyStr.c_str(), valStr.c_str());
361 attrs.emplace_back(keyStr, valStr);
362 }
363 }
364
SetDomAttributesWithObject(const shared_ptr<JsRuntime> & runtime,const std::string & keyStr,const shared_ptr<JsValue> & value,JsCommandDomElementOperator & command)365 void SetDomAttributesWithObject(const shared_ptr<JsRuntime>& runtime, const std::string& keyStr,
366 const shared_ptr<JsValue>& value, JsCommandDomElementOperator& command)
367 {
368 if (keyStr == "options") {
369 auto chartBridge = AceType::MakeRefPtr<JsiChartBridge>();
370 chartBridge->GetAttrOptionsObject(runtime, value);
371 command.SetOptions(chartBridge->GetChartOptions());
372 } else if (keyStr == "segments") {
373 auto chartBridge = AceType::MakeRefPtr<JsiChartBridge>();
374 chartBridge->ParseAttrSingleSegment(runtime, value);
375 command.SetSegments(chartBridge->GetSegments());
376 } else if (keyStr == DOM_CLOCK_CONFIG) {
377 auto clockBridge = AceType::MakeRefPtr<JsiClockBridge>();
378 clockBridge->ParseClockConfig(runtime, value);
379 command.SetClockConfig(clockBridge->GetClockConfig());
380 } else if (keyStr == DOM_NODE_TAG_LABEL) {
381 auto stepperBridge = AceType::MakeRefPtr<JsiStepperBridge>();
382 StepperLabels label;
383 stepperBridge->GetAttrLabel(runtime, value, label);
384 command.SetStepperLabel(label);
385 } else if (keyStr == DOM_BADGE_CONFIG) {
386 auto badgeBridge = AceType::MakeRefPtr<JsiBadgeBridge>();
387 badgeBridge->ParseBadgeConfig(runtime, value);
388 command.SetBadgeConfig(badgeBridge->GetBadgeConfig());
389 } else if (keyStr == DOM_STEPPER_LABEL) {
390 auto stepperBridge = AceType::MakeRefPtr<JsiStepperBridge>();
391 StepperLabels label;
392 stepperBridge->GetAttrLabel(runtime, value, label);
393 command.SetStepperLabel(label);
394 } else {
395 LOGD("key %{public}s unsupported. Ignoring!", keyStr.c_str());
396 }
397 }
398
SetDomAttributes(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & attrObj,JsCommandDomElementOperator & command)399 bool SetDomAttributes(
400 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& attrObj, JsCommandDomElementOperator& command)
401 {
402 LOGD("SetDomAttributes");
403 bool hasShowAttr = false;
404
405 if (!attrObj || !attrObj->IsObject(runtime)) {
406 return false;
407 }
408
409 int32_t len = 0;
410 shared_ptr<JsValue> properties;
411 attrObj->GetPropertyNames(runtime, properties, len);
412
413 std::vector<std::pair<std::string, std::string>> attrs;
414 for (int32_t i = 0; i < len; ++i) {
415 shared_ptr<JsValue> key = properties->GetElement(runtime, i);
416 if (!key) {
417 LOGE("key is null. Ignoring!");
418 continue;
419 }
420 shared_ptr<JsValue> value = attrObj->GetProperty(runtime, key);
421 std::string keyStr = key->ToString(runtime);
422 if (value->IsString(runtime) || value->IsNumber(runtime) || value->IsBoolean(runtime)) {
423 std::string valStr = value->ToString(runtime);
424 LOGD("SetDomAttributes: key %{private}s, attr: %{private}s", keyStr.c_str(), valStr.c_str());
425 if (keyStr == DOM_ID) {
426 command.SetId(valStr);
427 } else if (keyStr == DOM_TARGET) {
428 command.SetTarget(valStr);
429 } else if (keyStr == DOM_SHARE_ID) {
430 command.SetShareId(valStr);
431 }
432 attrs.emplace_back(keyStr, valStr);
433 if (keyStr == DOM_SHOW) {
434 hasShowAttr = true;
435 }
436 } else if (value->IsArray(runtime)) {
437 SetDomAttributesWithArray(runtime, keyStr, value, attrs, command);
438 } else if (value->IsObject(runtime)) {
439 SetDomAttributesWithObject(runtime, keyStr, value, command);
440 } else if (value->IsUndefined(runtime)) {
441 LOGE("value of key[%{private}s] is undefined. Ignoring!", keyStr.c_str());
442 } else {
443 LOGE("value of key[%{private}s] unsupported type. Ignoring!", keyStr.c_str());
444 }
445 }
446 command.SetAttributes(std::move(attrs));
447 return hasShowAttr;
448 }
449
SetDomStyle(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & styleObj,JsCommandDomElementOperator & command)450 void SetDomStyle(
451 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& styleObj, JsCommandDomElementOperator& command)
452 {
453 LOGD("SetDomStyle");
454 if (!styleObj || !styleObj->IsObject(runtime)) {
455 return;
456 }
457
458 int32_t len = 0;
459 shared_ptr<JsValue> properties;
460 styleObj->GetPropertyNames(runtime, properties, len);
461
462 std::vector<std::pair<std::string, std::string>> styles;
463 for (int32_t i = 0; i < len; ++i) {
464 shared_ptr<JsValue> key = properties->GetElement(runtime, i);
465 if (!key) {
466 LOGE("key is null. Ignoring!");
467 continue;
468 }
469 shared_ptr<JsValue> value = styleObj->GetProperty(runtime, key);
470 std::string keyStr = key->ToString(runtime);
471 if (value->IsString(runtime) || value->IsNumber(runtime) || value->IsBoolean(runtime)) {
472 std::string valStr = value->ToString(runtime);
473 LOGD("SetDomStyle: key: %{private}s, style: %{private}s", keyStr.c_str(), valStr.c_str());
474 styles.emplace_back(keyStr, valStr);
475 } else if (value->IsArray(runtime)) {
476 if (strcmp(keyStr.c_str(), DOM_TEXT_FONT_FAMILY) == 0) {
477 // Deal with special case such as fontFamily, suppose all the keys in the array are the same.
478 std::string familyStyle;
479 GetStyleFamilyValue(runtime, value, familyStyle);
480 styles.emplace_back(keyStr, familyStyle);
481 } else if (strcmp(keyStr.c_str(), DOM_ANIMATION_NAME) == 0) {
482 // Deal with special case animationName, it different with fontfamily,
483 // the keys in the array are different.
484 std::vector<std::unordered_map<std::string, std::string>> animationNameStyles;
485 GetStyleAnimationName(runtime, value, animationNameStyles);
486 command.SetAnimationStyles(std::move(animationNameStyles));
487 } else if (strcmp(keyStr.c_str(), DOM_TRANSITION_ENTER) == 0) {
488 std::vector<std::unordered_map<std::string, std::string>> transitionEnter;
489 GetStyleAnimationName(runtime, value, transitionEnter);
490 command.SetTransitionEnter(std::move(transitionEnter));
491 } else if (strcmp(keyStr.c_str(), DOM_TRANSITION_EXIT) == 0) {
492 std::vector<std::unordered_map<std::string, std::string>> transitionExit;
493 GetStyleAnimationName(runtime, value, transitionExit);
494 command.SetTransitionExit(std::move(transitionExit));
495 } else if (strcmp(keyStr.c_str(), DOM_SHARED_TRANSITION_NAME) == 0) {
496 std::vector<std::unordered_map<std::string, std::string>> sharedTransitionName;
497 GetStyleAnimationName(runtime, value, sharedTransitionName);
498 command.SetSharedTransitionName(std::move(sharedTransitionName));
499 } else {
500 LOGD("value is array, key unsupported. Ignoring!");
501 }
502 } else if (value->IsUndefined(runtime)) {
503 LOGD("value is undefined. Ignoring!");
504 } else {
505 LOGD("value of unsupported type. Ignoring!");
506 }
507 }
508
509 bool isIine = false;
510 for (int32_t i = 0; i < static_cast<int32_t>(styles.size()); i++) {
511 std::string key = styles[i].first;
512 std::string value = styles[i].second;
513 if (key == "display" && value == "inline") {
514 isIine = true;
515 break;
516 }
517 }
518
519 if (isIine) {
520 std::vector<std::pair<std::string, std::string>> stylesFinally;
521 for (int32_t i = 0; i < static_cast<int32_t>(styles.size()); i++) {
522 std::string key = styles[i].first;
523 std::string value = styles[i].second;
524 if (key == "width" || key == "height" || key.find("margin") != std::string::npos ||
525 key.find("padding") != std::string::npos) {
526 continue;
527 } else {
528 stylesFinally.emplace_back(key, value);
529 }
530 }
531 command.SetStyles(std::move(stylesFinally));
532 } else {
533 command.SetStyles(std::move(styles));
534 }
535 auto pipelineContext = AceType::DynamicCast<PipelineContext>(GetFrontendDelegate(runtime)->GetPipelineContext());
536 command.SetPipelineContext(pipelineContext);
537 }
538
AddDomEvent(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & eventObj,JsCommandDomElementOperator & command)539 void AddDomEvent(
540 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& eventObj, JsCommandDomElementOperator& command)
541 {
542 LOGD("AddDomEvent");
543
544 if (!eventObj || !eventObj->IsObject(runtime)) {
545 return;
546 }
547
548 int32_t len = 0;
549 shared_ptr<JsValue> properties;
550 eventObj->GetPropertyNames(runtime, properties, len);
551
552 std::vector<std::string> events;
553 for (int32_t i = 0; i < len; ++i) {
554 shared_ptr<JsValue> key = properties->GetElement(runtime, i);
555 if (!key) {
556 LOGE("key is null. Ignoring!");
557 continue;
558 }
559 shared_ptr<JsValue> value = eventObj->GetProperty(runtime, key);
560 std::string keyStr = key->ToString(runtime);
561 if (value->IsString(runtime)) {
562 std::string valStr = value->ToString(runtime);
563 events.emplace_back(valStr);
564 } else {
565 LOGW("value of unsupported type. Ignoring!");
566 }
567 }
568 command.AddEvents(std::move(events));
569 }
570
GetAppInfo(const shared_ptr<JsRuntime> & runtime)571 shared_ptr<JsValue> GetAppInfo(const shared_ptr<JsRuntime>& runtime)
572 {
573 LOGD("GetAppInfo");
574 auto delegate = GetFrontendDelegate(runtime);
575 shared_ptr<JsValue> appID = runtime->NewString(delegate->GetAppID());
576 shared_ptr<JsValue> appName = runtime->NewString(delegate->GetAppName());
577 shared_ptr<JsValue> versionName = runtime->NewString(delegate->GetVersionName());
578 shared_ptr<JsValue> versionCode = runtime->NewNumber(delegate->GetVersionCode());
579
580 // return the result as an object
581 shared_ptr<JsValue> res = runtime->NewObject();
582 res->SetProperty(runtime, "appID", appID);
583 res->SetProperty(runtime, "appName", appName);
584 res->SetProperty(runtime, "versionName", versionName);
585 res->SetProperty(runtime, "versionCode", versionCode);
586
587 return res;
588 }
589
Terminate(const shared_ptr<JsRuntime> & runtime)590 void Terminate(const shared_ptr<JsRuntime>& runtime)
591 {
592 auto delegate = GetFrontendDelegate(runtime);
593 WeakPtr<PipelineBase> pipelineContextWeak = delegate->GetPipelineContext();
594 auto uiTaskExecutor = delegate->GetUiTask();
595 uiTaskExecutor.PostTask([pipelineContextWeak]() mutable {
596 auto pipelineContext = pipelineContextWeak.Upgrade();
597 if (pipelineContext) {
598 pipelineContext->Finish();
599 }
600 });
601 }
602
GetPackageInfoCallback(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & message,const std::string & callbackId)603 void GetPackageInfoCallback(
604 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& message, const std::string& callbackId)
605 {
606 std::string arguments;
607 std::string methods;
608
609 if (!message || !message->IsObject(runtime)) {
610 LOGE("GetPackageInfoCallback: jsMessage is not Object");
611 arguments.append("{\"arguments\":[\"jsMessage is not Object\",200],");
612 methods.append("\"method\":\"fail\"}");
613 } else {
614 shared_ptr<JsValue> packageName = message->GetProperty(runtime, APP_PACKAGE_NAME);
615 if (!packageName->IsString(runtime) || packageName->ToString(runtime) == "") {
616 arguments.append("{\"arguments\":[\"packageName is not available string\",202],");
617 methods.append("\"method\":\"fail\"}");
618 } else {
619 AceBundleInfo bundleInfo;
620 if (!AceApplicationInfo::GetInstance().GetBundleInfo(packageName->ToString(runtime), bundleInfo)) {
621 LOGE("can not get info by GetBundleInfo");
622 arguments.append("{\"arguments\":[\"can not get info\",200],");
623 methods.append("\"method\":\"fail\"}");
624 } else {
625 auto infoList = JsonUtil::Create(true);
626 infoList->Put("versionName", bundleInfo.versionName.c_str());
627 infoList->Put("versionCode", std::to_string(bundleInfo.versionCode).c_str());
628 arguments.append("{\"arguments\":[").append(infoList->ToString()).append("],");
629 methods.append("\"method\":\"success\"}");
630 }
631 }
632 }
633
634 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
635 engineInstance->CallJs(callbackId, arguments + methods, false);
636 }
637
GetPackageInfo(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)638 void GetPackageInfo(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
639 {
640 LOGD("GetPackageInfo");
641 if (!arg->IsObject(runtime) || !arg->IsArray(runtime)) {
642 LOGE("GetPackageInfo: arg is not Object or Array");
643 return;
644 }
645
646 int32_t len = arg->GetArrayLength(runtime);
647 if (len < static_cast<int32_t>(PAG_INFO_ARGS_LEN)) {
648 LOGE("GetPackageInfo: invalid callback value");
649 return;
650 }
651 shared_ptr<JsValue> message = arg->GetElement(runtime, PAG_INFO_ARGS_MSG_IDX);
652 shared_ptr<JsValue> callBackId = arg->GetElement(runtime, 1);
653 std::string callbackIdStr = callBackId->ToString(runtime);
654 LOGD("system app getPackageInfo callBackID is %{private}s", callbackIdStr.c_str());
655
656 if (!callbackIdStr.empty()) {
657 GetPackageInfoCallback(runtime, message, callbackIdStr);
658 }
659 }
660
RequestFullWindow(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)661 void RequestFullWindow(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
662 {
663 int32_t duration = -1; // default scene
664 const int32_t customFullWindowLength = 2;
665 if (arg->IsArray(runtime)) {
666 int32_t len = arg->GetArrayLength(runtime);
667 if (len == customFullWindowLength) {
668 shared_ptr<JsValue> param = arg->GetElement(runtime, 0);
669 if (param && param->IsObject(runtime)) {
670 shared_ptr<JsValue> durationValue = param->GetProperty(runtime, APP_REQUEST_FULL_WINDOW_DURATION);
671 if (durationValue) {
672 std::string durationStr = durationValue->ToString(runtime);
673 if (!durationStr.empty()) {
674 duration = StringToInt(durationStr);
675 duration = duration >= 0 ? duration : -1;
676 }
677 }
678 }
679 }
680 }
681 auto delegate = GetFrontendDelegate(runtime);
682 WeakPtr<PipelineBase> pipelineContextWeak = delegate->GetPipelineContext();
683 auto uiTaskExecutor = delegate->GetUiTask();
684 uiTaskExecutor.PostTask([pipelineContextWeak, duration]() mutable {
685 auto pipelineContext = pipelineContextWeak.Upgrade();
686 if (pipelineContext) {
687 pipelineContext->RequestFullWindow(duration);
688 }
689 });
690 }
691
SetScreenOnVisible(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)692 void SetScreenOnVisible(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
693 {
694 std::map<std::string, std::string> params;
695 std::string callbackId;
696
697 static int32_t paramsLength = 2;
698 if (!arg->IsArray(runtime) || arg->GetArrayLength(runtime) < paramsLength) {
699 LOGE("SetScreenOnVisible, wrong args length!");
700 return;
701 }
702 // get params
703 shared_ptr<JsValue> paramObj = arg->GetElement(runtime, 0);
704 if (!paramObj || !paramObj->IsObject(runtime)) {
705 LOGE("SetScreenOnVisible, first argument is not an object!");
706 return;
707 }
708 int32_t len = 0;
709 shared_ptr<JsValue> properties;
710 if (!paramObj->GetPropertyNames(runtime, properties, len)) {
711 LOGE("SetScreenOnVisible, fail to get object property list!");
712 return;
713 }
714 for (int32_t i = 0; i < len; ++i) {
715 shared_ptr<JsValue> key = properties->GetElement(runtime, i);
716 shared_ptr<JsValue> val = paramObj->GetProperty(runtime, key);
717 std::string keyStr = key->ToString(runtime);
718 std::string valStr = val->ToString(runtime);
719 params.try_emplace(keyStr, valStr);
720 }
721 // get callbackId
722 callbackId = arg->GetElement(runtime, 1)->ToString(runtime);
723
724 std::string flag = "fail";
725 auto iter = params.find(APP_SCREEN_ON_VISIBLE_FLAG);
726 if (iter != params.end()) {
727 flag = iter->second;
728 }
729
730 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
731 if (!StringToBool(flag)) {
732 engineInstance->CallJs(
733 callbackId, R"({"arguments":["fail to set false flag in rich platform", 200],"method":"fail"})");
734 } else {
735 engineInstance->CallJs(callbackId, R"({"arguments":[],"method":"success"})");
736 }
737 }
738
GetLocale(const shared_ptr<JsRuntime> & runtime)739 shared_ptr<JsValue> GetLocale(const shared_ptr<JsRuntime>& runtime)
740 {
741 LOGD("GetLocale");
742
743 shared_ptr<JsValue> language = runtime->NewString(AceApplicationInfo::GetInstance().GetLanguage());
744 shared_ptr<JsValue> countryOrRegion = runtime->NewString(AceApplicationInfo::GetInstance().GetCountryOrRegion());
745 shared_ptr<JsValue> dir = runtime->NewString(
746 AceApplicationInfo::GetInstance().IsRightToLeft() ? LOCALE_TEXT_DIR_RTL : LOCALE_TEXT_DIR_LTR);
747
748 shared_ptr<JsValue> res = runtime->NewObject();
749 res->SetProperty(runtime, LOCALE_LANGUAGE, language);
750 res->SetProperty(runtime, LOCALE_COUNTRY_OR_REGION, countryOrRegion);
751 res->SetProperty(runtime, LOCALE_TEXT_DIR, dir);
752 return res;
753 }
754
SetLocale(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)755 void SetLocale(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
756 {
757 LOGD("SetLocale");
758 std::unique_ptr<JsonValue> localeJson = JsonUtil::ParseJsonString(arg->ToString(runtime));
759
760 if (localeJson) {
761 std::string language;
762 if (localeJson->GetValue(LOCALE_LANGUAGE) != nullptr && localeJson->GetValue(LOCALE_LANGUAGE)->IsString()) {
763 language = localeJson->GetValue(LOCALE_LANGUAGE)->GetString();
764 }
765 std::string countryOrRegion;
766 if (localeJson->GetValue(LOCALE_COUNTRY_OR_REGION) != nullptr &&
767 localeJson->GetValue(LOCALE_COUNTRY_OR_REGION)->IsString()) {
768 countryOrRegion = localeJson->GetValue(LOCALE_COUNTRY_OR_REGION)->GetString();
769 }
770 if (!countryOrRegion.empty() && !language.empty()) {
771 GetFrontendDelegate(runtime)->ChangeLocale(language, countryOrRegion);
772 }
773 }
774 }
775
GetDeviceInfo()776 std::string GetDeviceInfo()
777 {
778 LOGD("GetDeviceInfo");
779 auto infoList = JsonUtil::Create(true);
780 infoList->Put("brand", SystemProperties::GetBrand().c_str());
781 infoList->Put("manufacturer", SystemProperties::GetManufacturer().c_str());
782 infoList->Put("model", SystemProperties::GetModel().c_str());
783 infoList->Put("product", SystemProperties::GetProduct().c_str());
784 std::string tmp = SystemProperties::GetApiVersion();
785 if (tmp != SystemProperties::INVALID_PARAM) {
786 char* tmpEnd = nullptr;
787 infoList->Put("apiVersion", static_cast<int32_t>(
788 std::strtol(SystemProperties::GetApiVersion().c_str(), &tmpEnd, SYSTEM_BASE)));
789 } else {
790 infoList->Put("apiVersion", "N/A");
791 }
792 tmp = SystemProperties::GetReleaseType();
793 if (tmp != SystemProperties::INVALID_PARAM) {
794 infoList->Put("releaseType", tmp.c_str());
795 } else {
796 infoList->Put("releaseType", "N/A");
797 }
798 tmp = SystemProperties::GetParamDeviceType();
799 if (tmp != SystemProperties::INVALID_PARAM) {
800 infoList->Put("deviceType", tmp.c_str());
801 } else {
802 infoList->Put("deviceType", "N/A");
803 }
804 tmp = SystemProperties::GetLanguage();
805 if (tmp != SystemProperties::INVALID_PARAM) {
806 infoList->Put("language", tmp.c_str());
807 } else {
808 infoList->Put("language", "N/A");
809 }
810 tmp = SystemProperties::GetRegion();
811 if (tmp != SystemProperties::INVALID_PARAM) {
812 infoList->Put("region", tmp.c_str());
813 } else {
814 infoList->Put("region", "N/A");
815 }
816
817 auto container = Container::Current();
818 int32_t width = container ? container->GetViewWidth() : 0;
819 if (width != 0) {
820 infoList->Put("windowWidth", width);
821 } else {
822 infoList->Put("windowWidth", "N/A");
823 }
824
825 int32_t height = container ? container->GetViewHeight() : 0;
826 if (height != 0) {
827 infoList->Put("windowHeight", height);
828 } else {
829 infoList->Put("windowHeight", "N/A");
830 }
831
832 infoList->Put("screenDensity", SystemProperties::GetResolution());
833
834 bool isRound = SystemProperties::GetIsScreenRound();
835 if (isRound) {
836 infoList->Put("screenShape", "circle");
837 } else {
838 infoList->Put("screenShape", "rect");
839 }
840
841 return infoList->ToString();
842 }
843
ParseRouteUrl(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)844 std::string ParseRouteUrl(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& key)
845 {
846 LOGD("ParseRouteUrl");
847 std::string argStr = arg->ToString(runtime);
848 if (argStr.empty()) {
849 return argStr;
850 }
851
852 std::string pageRoute;
853 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
854 if (argsPtr != nullptr && argsPtr->GetValue(key) != nullptr && argsPtr->GetValue(key)->IsString()) {
855 pageRoute = argsPtr->GetValue(key)->GetString();
856 }
857 LOGD("JsParseRouteUrl pageRoute = %{private}s", pageRoute.c_str());
858
859 return pageRoute;
860 }
861
ParseRouteUrlSpecial(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)862 std::string ParseRouteUrlSpecial(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
863 {
864 std::string argStr = arg->ToString(runtime);
865 if (argStr.empty()) {
866 return argStr;
867 }
868
869 std::string pageRoute;
870 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
871
872 if (argsPtr->Contains(ROUTE_KEY_URI)) {
873 pageRoute = argsPtr->GetValue(ROUTE_KEY_URI)->GetString();
874 } else if (argsPtr->Contains(ROUTE_KEY_PATH)) {
875 pageRoute = argsPtr->GetValue(ROUTE_KEY_PATH)->GetString();
876 }
877 LOGD("JsParseRouteUrl pageRoute = %{private}s", pageRoute.c_str());
878
879 return pageRoute;
880 }
881
ParseRouteParams(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)882 std::string ParseRouteParams(
883 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& key)
884 {
885 std::string argStr = arg->ToString(runtime);
886 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
887 std::string params;
888 if (argsPtr != nullptr && argsPtr->Contains(key) && argsPtr->GetValue(key)->IsObject()) {
889 params = argsPtr->GetValue(key)->ToString();
890 }
891 return params;
892 }
893
ParseIntParams(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)894 int32_t ParseIntParams(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& key)
895 {
896 std::string argStr = arg->ToString(runtime);
897 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
898 int32_t params = 0;
899 if (argsPtr != nullptr && argsPtr->Contains(key) && argsPtr->GetValue(key)->IsNumber()) {
900 params = argsPtr->GetValue(key)->GetInt();
901 }
902 return params;
903 }
904
ParseRouteOverwrite(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)905 bool ParseRouteOverwrite(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& key)
906 {
907 std::string argStr = arg->ToString(runtime);
908
909 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
910 if (argsPtr != nullptr && argsPtr->Contains(key)) {
911 return true;
912 }
913 return false;
914 }
915
AddListener(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)916 void AddListener(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
917 {
918 if (arg->IsObject(runtime) && arg->IsArray(runtime)) {
919 int32_t len = arg->GetArrayLength(runtime);
920 if (len == 0) {
921 return;
922 }
923 std::string listenerId = arg->GetElement(runtime, 0)->ToString(runtime);
924 auto mediaQuery = GetFrontendDelegate(runtime)->GetMediaQueryInfoInstance();
925 if (mediaQuery && !listenerId.empty()) {
926 mediaQuery->SetListenerId(listenerId);
927 }
928 }
929 }
930
ShowToast(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)931 void ShowToast(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
932 {
933 LOGD("ShowToast");
934 std::string argStr = arg->ToString(runtime);
935
936 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
937 std::string message;
938 int32_t duration = 0;
939 std::string bottom;
940 if (argsPtr != nullptr) {
941 if (argsPtr->GetValue(PROMPT_KEY_MESSAGE) != nullptr) {
942 if (argsPtr->GetValue(PROMPT_KEY_MESSAGE)->IsString()) {
943 message = argsPtr->GetValue(PROMPT_KEY_MESSAGE)->GetString();
944 } else {
945 message = argsPtr->GetValue(PROMPT_KEY_MESSAGE)->ToString();
946 }
947 }
948 if (argsPtr->GetValue(PROMPT_KEY_DURATION) != nullptr && argsPtr->GetValue(PROMPT_KEY_DURATION)->IsNumber()) {
949 duration = argsPtr->GetValue(PROMPT_KEY_DURATION)->GetInt();
950 }
951 if (argsPtr->GetValue(PROMPT_KEY_BOTTOM) != nullptr) {
952 if (argsPtr->GetValue(PROMPT_KEY_BOTTOM)->IsString()) {
953 bottom = argsPtr->GetValue(PROMPT_KEY_BOTTOM)->GetString();
954 } else if (argsPtr->GetValue(PROMPT_KEY_BOTTOM)->IsNumber()) {
955 bottom = std::to_string(argsPtr->GetValue(PROMPT_KEY_BOTTOM)->GetInt());
956 }
957 }
958 }
959 LOGD("ShowToast message = %{private}s duration = %{public}d bottom = %{private}s", message.c_str(), duration,
960 bottom.c_str());
961
962 GetFrontendDelegate(runtime)->ShowToast(message, duration, bottom);
963 }
964
ParseDialogButtons(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & key)965 std::vector<ButtonInfo> ParseDialogButtons(
966 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& key)
967 {
968 std::vector<ButtonInfo> dialogButtons;
969 std::string argStr = arg->ToString(runtime);
970 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argStr);
971 if (argsPtr != nullptr && argsPtr->GetValue(key) != nullptr && argsPtr->GetValue(key)->IsArray()) {
972 for (int32_t i = 0; i < argsPtr->GetValue(key)->GetArraySize(); ++i) {
973 auto button = argsPtr->GetValue(key)->GetArrayItem(i);
974 ButtonInfo buttonInfo;
975 if (button->GetValue("text")) {
976 buttonInfo.text = button->GetValue("text")->GetString();
977 }
978 if (button->GetValue("color")) {
979 buttonInfo.textColor = button->GetValue("color")->GetString();
980 }
981 dialogButtons.emplace_back(buttonInfo);
982 }
983 }
984 return dialogButtons;
985 }
986
ShowDialog(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)987 void ShowDialog(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
988 {
989 LOGD("ShowDialog");
990
991 const std::string title = ParseRouteUrl(runtime, arg, PROMPT_KEY_TITLE);
992 const std::string message = ParseRouteUrl(runtime, arg, PROMPT_KEY_MESSAGE);
993 std::vector<ButtonInfo> buttons = ParseDialogButtons(runtime, arg, PROMPT_KEY_BUTTONS);
994 const std::string success = ParseRouteUrl(runtime, arg, COMMON_SUCCESS);
995 const std::string cancel = ParseRouteUrl(runtime, arg, COMMON_CANCEL);
996 const std::string complete = ParseRouteUrl(runtime, arg, COMMON_COMPLETE);
997 bool autoCancel = true;
998
999 std::string argsStr = arg->ToString(runtime);
1000 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(argsStr);
1001 if (argsPtr != nullptr && argsPtr->GetValue(PROMPT_DIALOG_AUTO_CANCEL) != nullptr &&
1002 argsPtr->GetValue(PROMPT_DIALOG_AUTO_CANCEL)->IsBool()) {
1003 autoCancel = argsPtr->GetValue(PROMPT_DIALOG_AUTO_CANCEL)->GetBool();
1004 }
1005
1006 std::set<std::string> callbacks;
1007 if (!success.empty()) {
1008 callbacks.emplace(COMMON_SUCCESS);
1009 }
1010 if (!cancel.empty()) {
1011 callbacks.emplace(COMMON_CANCEL);
1012 }
1013 if (!complete.empty()) {
1014 callbacks.emplace(COMMON_COMPLETE);
1015 }
1016
1017 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1018 auto callback = [engineInstance, success, cancel, complete](int32_t callbackType, int32_t successType) {
1019 switch (callbackType) {
1020 case 0:
1021 engineInstance->CallJs(
1022 success, std::string("{\"index\":").append(std::to_string(successType)).append("}"), false);
1023 break;
1024 case 1:
1025 engineInstance->CallJs(cancel, std::string("\"cancel\",null"), false);
1026 break;
1027 case 2:
1028 engineInstance->CallJs(complete, std::string("\"complete\",null"), false);
1029 break;
1030 default:
1031 break;
1032 }
1033 };
1034
1035 GetFrontendDelegate(runtime)->ShowDialog(title, message, buttons, autoCancel, std::move(callback), callbacks);
1036 }
1037
SetTimer(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,bool isInterval)1038 void SetTimer(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, bool isInterval)
1039 {
1040 LOGD("SetTimer");
1041 if (arg->IsArray(runtime)) {
1042 int32_t len = arg->GetArrayLength(runtime);
1043 if (len < 2) {
1044 LOGW("SetTimer: invalid callback value");
1045 return;
1046 }
1047 std::string callBackId = arg->GetElement(runtime, 0)->ToString(runtime);
1048 std::string delay = arg->GetElement(runtime, 1)->ToString(runtime);
1049 if (!callBackId.empty() && !delay.empty()) {
1050 GetFrontendDelegate(runtime)->WaitTimer(callBackId, delay, isInterval, true);
1051 }
1052 }
1053 }
1054
ClearTimeout(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1055 void ClearTimeout(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1056 {
1057 LOGD("ClearTimeout");
1058
1059 if (arg->IsArray(runtime)) {
1060 int32_t len = arg->GetArrayLength(runtime);
1061 if (len < 1) {
1062 LOGW("ClearTimeout: invalid callback value");
1063 return;
1064 }
1065 std::string callBackId = arg->GetElement(runtime, 0)->ToString(runtime);
1066 if (!callBackId.empty()) {
1067 GetFrontendDelegate(runtime)->ClearTimer(callBackId);
1068 }
1069 }
1070 }
1071
JsHandleAnimationFrame(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1072 shared_ptr<JsValue> JsHandleAnimationFrame(
1073 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1074 {
1075 std::string callbackId = arg->ToString(runtime);
1076 if (callbackId.empty()) {
1077 LOGW("system animation callbackId is null");
1078 return runtime->NewNull();
1079 }
1080
1081 if (methodName == ANIMATION_REQUEST_ANIMATION_FRAME) {
1082 GetFrontendDelegate(runtime)->RequestAnimationFrame(callbackId);
1083 } else if (methodName == ANIMATION_CANCEL_ANIMATION_FRAME) {
1084 GetFrontendDelegate(runtime)->CancelAnimationFrame(callbackId);
1085 } else {
1086 LOGW("animationFrame not support method = %{private}s", methodName.c_str());
1087 }
1088 return runtime->NewNull();
1089 }
1090
JsHandleCallback(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1091 shared_ptr<JsValue> JsHandleCallback(
1092 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1093 {
1094 if (methodName == CALLBACK_NATIVE) {
1095 if (arg->IsObject(runtime) && arg->IsArray(runtime)) {
1096 shared_ptr<JsValue> callbackId = arg->GetProperty(runtime, 0);
1097 shared_ptr<JsValue> result = arg->GetProperty(runtime, 1);
1098 std::string callbackIdStr = callbackId->ToString(runtime);
1099 std::string resultStr = result->ToString(runtime);
1100
1101 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(resultStr);
1102 if (argsPtr && argsPtr->GetValue(KEY_STEPPER_PENDING_INDEX) != nullptr) {
1103 auto jsonValue = argsPtr->GetValue(KEY_STEPPER_PENDING_INDEX);
1104 if (jsonValue->IsString()) {
1105 resultStr = jsonValue->GetString();
1106 } else if (jsonValue->IsNumber()) {
1107 resultStr = jsonValue->ToString();
1108 }
1109 }
1110 GetFrontendDelegate(runtime)->SetCallBackResult(callbackIdStr, resultStr);
1111 }
1112 } else if (methodName == APP_DESTROY_FINISH) {
1113 LOGD("JsHandleCallback: appDestroyFinish should release resource here");
1114 } else {
1115 LOGW("internal.jsResult not support method = %{private}s", methodName.c_str());
1116 }
1117
1118 return runtime->NewNull();
1119 }
1120
JsHandleAppApi(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1121 shared_ptr<JsValue> JsHandleAppApi(
1122 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1123 {
1124 if (methodName == APP_GET_INFO) {
1125 return GetAppInfo(runtime);
1126 } else if (methodName == APP_TERMINATE) {
1127 Terminate(runtime);
1128 } else if (methodName == APP_GET_PACKAGE_INFO) {
1129 GetPackageInfo(runtime, arg);
1130 } else if (methodName == APP_REQUEST_FULL_WINDOW) {
1131 RequestFullWindow(runtime, arg);
1132 } else if (methodName == APP_SCREEN_ON_VISIBLE) {
1133 SetScreenOnVisible(runtime, arg);
1134 } else {
1135 LOGW("system.app not support method = %{private}s", methodName.c_str());
1136 }
1137 return runtime->NewNull();
1138 }
1139
JsParseRouteUrl(const std::unique_ptr<JsonValue> & argsPtr,const std::string & key)1140 std::string JsParseRouteUrl(const std::unique_ptr<JsonValue>& argsPtr, const std::string& key)
1141 {
1142 std::string pageRoute;
1143 if (argsPtr != nullptr && argsPtr->GetValue(key) != nullptr && argsPtr->GetValue(key)->IsString()) {
1144 pageRoute = argsPtr->GetValue(key)->GetString();
1145 }
1146 return pageRoute;
1147 }
1148
GetParams(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,std::map<std::string,std::string> & params)1149 bool GetParams(
1150 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, std::map<std::string, std::string>& params)
1151 {
1152 if (!runtime) {
1153 LOGE("fail to get params due to runtime is illegal");
1154 return false;
1155 }
1156 int32_t len = 0;
1157 shared_ptr<JsValue> properties;
1158 if (!arg->GetPropertyNames(runtime, properties, len)) {
1159 LOGE("GetParams fail to get object property list!");
1160 return false;
1161 }
1162 for (int32_t i = 0; i < len; ++i) {
1163 shared_ptr<JsValue> key = properties->GetElement(runtime, i);
1164 shared_ptr<JsValue> val = arg->GetProperty(runtime, key);
1165 std::string keyStr = key->ToString(runtime);
1166 std::string valStr = val->ToString(runtime);
1167 params[keyStr] = valStr;
1168 }
1169 return true;
1170 }
1171
GetParamsWithCallbackId(const shared_ptr<JsRuntime> & runtime,const std::vector<shared_ptr<JsValue>> & argv,std::map<std::string,std::string> & params,std::string & callbackId)1172 bool GetParamsWithCallbackId(const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1173 std::map<std::string, std::string>& params, std::string& callbackId)
1174 {
1175 if (!runtime) {
1176 LOGE("fail to get params due to runtime is illegal");
1177 return false;
1178 }
1179 if (argv.size() < 2) {
1180 LOGE("fail to get params due to length is illegal");
1181 return false;
1182 }
1183 if (!GetParams(runtime, argv[0], params)) {
1184 return false;
1185 }
1186 if (!argv[1]->IsString(runtime)) {
1187 return false;
1188 }
1189 callbackId = argv[1]->ToString(runtime);
1190 return true;
1191 }
1192
ParseResourceStringParam(const char * paramName,const std::map<std::string,std::string> & params,std::string & str)1193 bool ParseResourceStringParam(const char* paramName, const std::map<std::string, std::string>& params, std::string& str)
1194 {
1195 std::string strName(paramName);
1196 auto iter = params.find(strName);
1197 if (iter != params.end()) {
1198 str = iter->second;
1199 return true;
1200 }
1201 return false;
1202 }
1203
ParseResourceNumberParam(const char * paramName,const std::map<std::string,std::string> & params,int32_t & num)1204 bool ParseResourceNumberParam(const char* paramName, const std::map<std::string, std::string>& params, int32_t& num)
1205 {
1206 std::string numName(paramName);
1207 auto iter = params.find(numName);
1208 if (iter != params.end()) {
1209 num = ParseResourceInputNumberParam(iter->second);
1210 return true;
1211 }
1212 return false;
1213 }
1214
ParseResourceParam(const std::map<std::string,std::string> & params,std::string & uri,int32_t & position,int32_t & length)1215 void ParseResourceParam(
1216 const std::map<std::string, std::string>& params, std::string& uri, int32_t& position, int32_t& length)
1217 {
1218 ParseResourceStringParam(READ_KEY_URI, params, uri);
1219 ParseResourceNumberParam(READ_KEY_POSITION, params, position);
1220 ParseResourceNumberParam(READ_KEY_LENGTH, params, length);
1221 }
1222
JsReadText(const shared_ptr<JsRuntime> & runtime,const std::vector<shared_ptr<JsValue>> & argv)1223 shared_ptr<JsValue> JsReadText(const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv)
1224 {
1225 if (!runtime) {
1226 LOGE("JsReadText failed. runtime is null.");
1227 return nullptr;
1228 }
1229 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1230 if (!engine) {
1231 LOGE("JsReadText failed. engine is null.");
1232 return runtime->NewUndefined();
1233 }
1234 std::map<std::string, std::string> params;
1235 std::string callbackId;
1236 if (!GetParamsWithCallbackId(runtime, argv, params, callbackId)) {
1237 LOGE("JsReadText, get params or callbackId failed!");
1238 return runtime->NewUndefined();
1239 }
1240 std::string uri;
1241 ParseResourceStringParam(READ_KEY_URI, params, uri);
1242 std::smatch result;
1243 if (!std::regex_match(uri, result, URI_PATTERN)) {
1244 LOGE("JsReadText uri regex match failed");
1245 engine->CallJs(callbackId, R"({"arguments":["file uri pattern not correct", 202],"method":"fail"})");
1246 return runtime->NewUndefined();
1247 }
1248
1249 std::string fileText;
1250 auto delegate = engine->GetFrontendDelegate();
1251 if (!delegate) {
1252 LOGE("JsReadText failed. delegate is null.");
1253 return runtime->NewUndefined();
1254 }
1255 if (!(delegate->GetResourceData(uri, fileText))) {
1256 LOGE("JsReadText get text data failed");
1257 engine->CallJs(callbackId, R"({"arguments":["get text data failed", 301],"method":"fail"})");
1258 return runtime->NewUndefined();
1259 }
1260
1261 auto fileLength = ParseUtf8TextLength(fileText);
1262 int32_t position = 0;
1263 int32_t length = 0;
1264 if (!ParseResourceNumberParam(READ_KEY_POSITION, params, position)) {
1265 position = 1;
1266 }
1267
1268 if (!ParseResourceNumberParam(READ_KEY_LENGTH, params, length) || (length > fileLength - position + 1)) {
1269 length = (fileLength - position + 1 <= 0) ? 0 : fileLength - position + 1;
1270 }
1271
1272 if (fileLength == 0) {
1273 if ((position <= 0) || (length < 0)) {
1274 engine->CallJs(
1275 callbackId, R"({"arguments":["wrong start position or wrong read length", 202],"method":"fail"})");
1276 return runtime->NewUndefined();
1277 }
1278 } else {
1279 if ((position > fileLength) || (position <= 0) || (length < 0)) {
1280 engine->CallJs(
1281 callbackId, R"({"arguments":["wrong start position or wrong read length", 202],"method":"fail"})");
1282 return runtime->NewUndefined();
1283 }
1284
1285 size_t substrPos = static_cast<size_t>(ParseUtf8TextSubstrStartPos(fileText, position));
1286 size_t substrEndPos = static_cast<size_t>(ParseUtf8TextSubstrEndPos(fileText, position + length - 1));
1287 fileText = fileText.substr(substrPos - 1, substrEndPos - substrPos + 1);
1288 HandleEscapeCharaterInUtf8TextForJson(fileText);
1289 }
1290
1291 engine->CallJs(callbackId,
1292 std::string("{\"arguments\":[").append("{\"text\":\"").append(fileText).append("\"}],\"method\":\"success\"}"));
1293 return runtime->NewUndefined();
1294 }
1295
JsReadArrayBuffer(const shared_ptr<JsRuntime> & runtime,const std::vector<shared_ptr<JsValue>> & argv)1296 shared_ptr<JsValue> JsReadArrayBuffer(
1297 const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv)
1298 {
1299 if (!runtime) {
1300 LOGE("JsReadArrayBuffer failed. runtime is null.");
1301 return nullptr;
1302 }
1303 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1304 if (!engine) {
1305 LOGE("JsReadArrayBuffer failed. engine is null.");
1306 return runtime->NewUndefined();
1307 }
1308 std::map<std::string, std::string> params;
1309 std::string callbackId;
1310 if (!GetParamsWithCallbackId(runtime, argv, params, callbackId)) {
1311 LOGE("JsReadArrayBuffer, get params or callbackId failed!");
1312 return runtime->NewUndefined();
1313 }
1314 std::string uri;
1315 int32_t position = 1;
1316 int32_t length = MAX_READ_TEXT_LENGTH;
1317 ParseResourceParam(params, uri, position, length);
1318 std::smatch result;
1319 if (!std::regex_match(uri, result, URI_PATTERN)) {
1320 LOGE("JsReadArrayBuffer uri regex match failed");
1321 engine->CallJs(callbackId, R"({"arguments":["file uri pattern not correct", 200],"method":"fail"})");
1322 return runtime->NewUndefined();
1323 }
1324
1325 auto delegate = engine->GetFrontendDelegate();
1326 if (!delegate) {
1327 LOGE("JsReadArrayBuffer failed. delegate is null.");
1328 return runtime->NewUndefined();
1329 }
1330 std::vector<uint8_t> binaryContent;
1331 if (!(delegate->GetResourceData(uri, binaryContent))) {
1332 LOGE("JsReadArrayBuffer get buffer data failed");
1333 engine->CallJs(callbackId, R"({"arguments":["get buffer data failed", 301],"method":"fail"})");
1334 return runtime->NewUndefined();
1335 }
1336
1337 auto fileLength = static_cast<int32_t>(binaryContent.size());
1338 if (position > fileLength || position <= 0 || length <= 0) {
1339 LOGE("JsReadArrayBuffer position fileLength failed");
1340 engine->CallJs(
1341 callbackId, R"({"arguments":["wrong start position or wrong read length", 301],"method":"fail"})");
1342 return runtime->NewUndefined();
1343 }
1344
1345 length = position + length - 1 > fileLength ? fileLength - position + 1 : length;
1346 shared_ptr<JsValue> binaryData = runtime->NewObject();
1347 shared_ptr<JsValue> binaryArray = runtime->NewArray();
1348 for (int32_t i = 0; i < length; ++i) {
1349 binaryArray->SetProperty(runtime, runtime->NewInt32(i), runtime->NewInt32(binaryContent[position - 1 + i]));
1350 }
1351 binaryData->SetProperty(runtime, "buffer", binaryArray);
1352 engine->CallJs(callbackId, R"({"arguments":["read array buffer success"],"method":"success"})");
1353 return binaryData;
1354 }
1355
JsHandleReadResource(const shared_ptr<JsRuntime> & runtime,const std::vector<shared_ptr<JsValue>> & argv,const std::string & methodName)1356 shared_ptr<JsValue> JsHandleReadResource(
1357 const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv, const std::string& methodName)
1358 {
1359 LOGD("JsHandleReadResource");
1360 if (methodName == READ_TEXT) {
1361 return JsReadText(runtime, argv);
1362 } else if (methodName == READ_ARRAY_BUFFER) {
1363 return JsReadArrayBuffer(runtime, argv);
1364 } else {
1365 LOGW("system.resource not support method = %{private}s", methodName.c_str());
1366 }
1367 return runtime->NewUndefined();
1368 }
1369
JsHandleOffscreenCanvas(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1370 shared_ptr<JsValue> JsHandleOffscreenCanvas(
1371 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1372 {
1373 auto page = GetRunningPage(runtime);
1374 if (page == nullptr) {
1375 return runtime->NewUndefined();
1376 }
1377
1378 if (methodName == OFFSCREEN_CANVAS_CREATE) {
1379 int32_t width = ParseIntParams(runtime, arg, "width");
1380 int32_t height = ParseIntParams(runtime, arg, "height");
1381
1382 auto pipelineContext = GetFrontendDelegate(runtime)->GetPipelineContext();
1383 auto bridge = AceType::MakeRefPtr<JsiOffscreenCanvasBridge>(pipelineContext, width, height);
1384 page->PushOffscreenCanvasBridge(bridge->GetBridgeId(), bridge);
1385 return bridge->GetBridge(runtime);
1386 }
1387 return runtime->NewUndefined();
1388 }
1389
JsCallConfiguration(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1390 shared_ptr<JsValue> JsCallConfiguration(
1391 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1392 {
1393 if (CONFIGURATION_GET_LOCALE == methodName) {
1394 return GetLocale(runtime);
1395 } else if (CONFIGURATION_SET_LOCALE == methodName) {
1396 SetLocale(runtime, arg);
1397 }
1398 return runtime->NewNull();
1399 }
1400
JsGetDeviceInfo(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1401 shared_ptr<JsValue> JsGetDeviceInfo(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1402 {
1403 std::string callbackId = arg->ToString(runtime);
1404 if (callbackId.empty()) {
1405 LOGE("system device getInfo callBackID is null");
1406 } else {
1407 LOGD("system device getInfo callBackID = %{private}s", callbackId.c_str());
1408 std::string info = GetDeviceInfo();
1409 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1410 if (info.find("N/A") != std::string::npos) {
1411 engineInstance->CallJs(
1412 callbackId, std::string("{\"arguments\":[").append(info).append(",200],\"method\":\"fail\"}"), false);
1413 } else {
1414 engineInstance->CallJs(
1415 callbackId, std::string("{\"arguments\":[").append(info).append("],\"method\":\"success\"}"), false);
1416 }
1417 }
1418
1419 return runtime->NewNull();
1420 }
1421
JsHandleImage(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1422 shared_ptr<JsValue> JsHandleImage(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1423 {
1424 auto src = ParseRouteUrl(runtime, arg, "src");
1425 auto success = ParseRouteUrl(runtime, arg, "success");
1426 auto fail = ParseRouteUrl(runtime, arg, "fail");
1427
1428 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1429 if (!engineInstance) {
1430 return runtime->NewNull();
1431 }
1432
1433 auto&& callback = [engineInstance, success, fail](bool callbackType, int32_t width, int32_t height) {
1434 if (callbackType) {
1435 engineInstance->CallJs(success,
1436 std::string("{\"width\":")
1437 .append(std::to_string(width))
1438 .append(", \"height\":")
1439 .append(std::to_string(height))
1440 .append("}"),
1441 false);
1442 } else {
1443 engineInstance->CallJs(fail, std::string("\"fail\",null"), false);
1444 }
1445 };
1446 engineInstance->GetFrontendDelegate()->HandleImage(src, callback);
1447 return runtime->NewNull();
1448 }
1449
JsHandleGridLayout(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1450 shared_ptr<JsValue> JsHandleGridLayout(
1451 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1452 {
1453 if (!runtime) {
1454 LOGE("JsHandleGridLayout failed. runtime is null.");
1455 return nullptr;
1456 }
1457 if (methodName == GRID_GET_SYSTEM_LAYOUT_INFO) {
1458 return runtime->NewString(GridSystemManager::GetInstance().GetCurrentGridInfo().ToString());
1459 } else {
1460 LOGW("grid not support method = %{public}s", methodName.c_str());
1461 return runtime->NewUndefined();
1462 }
1463 }
1464
JsHandleMediaQuery(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1465 shared_ptr<JsValue> JsHandleMediaQuery(
1466 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1467 {
1468 if (methodName == ADD_LISTENER) {
1469 AddListener(runtime, arg);
1470 } else if (methodName == GET_DEVICE_TYPE) {
1471 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1472 if (engineInstance) {
1473 auto mediaQuery = engineInstance->GetFrontendDelegate()->GetMediaQueryInfoInstance();
1474 if (mediaQuery) {
1475 return runtime->NewString(mediaQuery->GetDeviceType());
1476 }
1477 }
1478 } else {
1479 LOGW("system.mediaquery not support method = %{private}s", methodName.c_str());
1480 }
1481 return runtime->NewNull();
1482 }
1483
JsParseDialogButtons(const std::unique_ptr<JsonValue> & argsPtr,const std::string & key)1484 std::vector<ButtonInfo> JsParseDialogButtons(const std::unique_ptr<JsonValue>& argsPtr, const std::string& key)
1485 {
1486 std::vector<ButtonInfo> dialogButtons;
1487 if (argsPtr != nullptr && argsPtr->GetValue(key) != nullptr && argsPtr->GetValue(key)->IsArray()) {
1488 for (int32_t i = 0; i < argsPtr->GetValue(key)->GetArraySize(); i++) {
1489 auto button = argsPtr->GetValue(key)->GetArrayItem(i);
1490 if (!button->GetValue("text")->IsString()) {
1491 continue;
1492 }
1493 ButtonInfo buttonInfo;
1494 if (button->GetValue("text")) {
1495 buttonInfo.text = button->GetValue("text")->GetString();
1496 }
1497 if (button->GetValue("color")) {
1498 buttonInfo.textColor = button->GetValue("color")->GetString();
1499 }
1500 dialogButtons.emplace_back(buttonInfo);
1501 }
1502 }
1503 return dialogButtons;
1504 }
1505
ShowActionMenu(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1506 void ShowActionMenu(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1507 {
1508 if (!runtime) {
1509 LOGE("ShowActionMenu failed. runtime is null.");
1510 return;
1511 }
1512 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1513 if (!engine) {
1514 LOGE("ShowActionMenu failed. engine is null.");
1515 return;
1516 }
1517 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(arg->ToString(runtime));
1518 if (argsPtr == nullptr) {
1519 LOGE("ShowActionMenu failed. argsPtr is nullptr");
1520 return;
1521 }
1522 std::vector<ButtonInfo> buttons = JsParseDialogButtons(argsPtr, PROMPT_KEY_BUTTONS);
1523 if (buttons.empty() || buttons.size() > 6) { // The number of buttons cannot be zero or more than six
1524 LOGE("buttons is invalid");
1525 if (argsPtr->IsObject()) {
1526 const std::string fail = JsParseRouteUrl(argsPtr, COMMON_FAIL);
1527 const std::string complete = JsParseRouteUrl(argsPtr, COMMON_COMPLETE);
1528 engine->CallJs(fail, R"({"errMsg":"enableAlertBeforeBackPage:buttons is invalid"})");
1529 engine->CallJs(complete, R"({"errMsg":"enableAlertBeforeBackPage:buttons is invalid"})");
1530 } else {
1531 std::string callBackStr = arg->ToString(runtime);
1532 // Get callbackId and clear redundant symbols, 2 is available min string length
1533 if (callBackStr.size() > 2 && callBackStr.front() == '\"' && callBackStr.back() == '\"') {
1534 callBackStr = callBackStr.substr(1, callBackStr.size() - 2);
1535 engine->CallJs(callBackStr,
1536 R"({"arguments":[{"errMsg":"enableAlertBeforeBackPage:buttons is invalid"}],"method":"fail"})");
1537 }
1538 }
1539 return;
1540 }
1541
1542 const std::string title = JsParseRouteUrl(argsPtr, PROMPT_KEY_TITLE);
1543 const std::string success = JsParseRouteUrl(argsPtr, COMMON_SUCCESS);
1544 const std::string fail = JsParseRouteUrl(argsPtr, COMMON_FAIL);
1545 const std::string complete = JsParseRouteUrl(argsPtr, COMMON_COMPLETE);
1546 auto callback = [engine, success, fail, complete](int32_t callbackType, int32_t successType) {
1547 switch (callbackType) {
1548 case 0:
1549 engine->CallJs(success, std::string(R"({"errMsg":"showActionMenu:ok","tapIndex":)")
1550 .append(std::to_string(successType))
1551 .append("}")
1552 .c_str());
1553 engine->CallJs(complete, std::string(R"({"errMsg":"showActionMenu:ok","tapIndex":)")
1554 .append(std::to_string(successType))
1555 .append("}")
1556 .c_str());
1557 break;
1558 case 1:
1559 engine->CallJs(fail, R"({"errMsg":"showActionMenu:fail cancel"})");
1560 engine->CallJs(complete, R"({"errMsg":"showActionMenu:fail cancel"})");
1561 break;
1562 default:
1563 LOGE("callbackType is invalid");
1564 break;
1565 }
1566 };
1567 auto delegate = engine->GetFrontendDelegate();
1568 if (!delegate) {
1569 LOGE("ShowActionMenu failed. delegate is null.");
1570 return;
1571 }
1572 delegate->ShowActionMenu(title, buttons, std::move(callback));
1573 }
1574
JsHandlePrompt(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1575 shared_ptr<JsValue> JsHandlePrompt(
1576 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1577 {
1578 if (methodName == PROMPT_SHOW_TOAST) {
1579 ShowToast(runtime, arg);
1580 } else if (methodName == PROMPT_SHOW_DIALOG) {
1581 ShowDialog(runtime, arg);
1582 } else if (methodName == PROMPT_SHOW_ACTION_MENU) {
1583 ShowActionMenu(runtime, arg);
1584 } else {
1585 LOGW("system.prompt not support method = %{private}s", methodName.c_str());
1586 }
1587 return runtime->NewNull();
1588 }
1589
EnableAlertBeforeBackPage(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1590 shared_ptr<JsValue> EnableAlertBeforeBackPage(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1591 {
1592 if (!runtime) {
1593 LOGE("EnableAlertBeforeBackPage failed. runtime is null.");
1594 return nullptr;
1595 }
1596 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1597 if (!engine) {
1598 LOGE("EnableAlertBeforeBackPage failed. engine is null.");
1599 return runtime->NewUndefined();
1600 }
1601 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(arg->ToString(runtime));
1602 if (argsPtr != nullptr && argsPtr->IsObject()) {
1603 if (argsPtr->GetValue(PROMPT_KEY_MESSAGE) == nullptr || !argsPtr->GetValue(PROMPT_KEY_MESSAGE)->IsString()) {
1604 LOGE("enableAlertBeforeBackPage message is null");
1605 const std::string fail = JsParseRouteUrl(argsPtr, COMMON_FAIL);
1606 const std::string complete = JsParseRouteUrl(argsPtr, COMMON_COMPLETE);
1607 engine->CallJs(fail, R"({"errMsg":"enableAlertBeforeBackPage:massage is null"})");
1608 engine->CallJs(complete, R"({"errMsg":"enableAlertBeforeBackPage:massage is null"})");
1609 return runtime->NewUndefined();
1610 }
1611 } else {
1612 LOGE("enableAlertBeforeBackPage message is null");
1613 std::string callBackStr = arg->ToString(runtime);
1614 // Get callbackId and clear redundant symbols, 2 is available min string length
1615 if (callBackStr.size() > 2 && callBackStr.front() == '\"' && callBackStr.back() == '\"') {
1616 callBackStr = callBackStr.substr(1, callBackStr.size() - 2);
1617 engine->CallJs(callBackStr,
1618 R"({"arguments":[{"errMsg":"enableAlertBeforeBackPage:massage is null"}],"method":"fail"})");
1619 }
1620 return runtime->NewUndefined();
1621 }
1622
1623 const std::string message = JsParseRouteUrl(argsPtr, PROMPT_KEY_MESSAGE);
1624 const std::string success = JsParseRouteUrl(argsPtr, COMMON_SUCCESS);
1625 const std::string fail = JsParseRouteUrl(argsPtr, COMMON_FAIL);
1626 const std::string complete = JsParseRouteUrl(argsPtr, COMMON_COMPLETE);
1627 auto callback = [engine, success, fail, complete](int32_t callbackType) {
1628 switch (callbackType) {
1629 case 1:
1630 engine->CallJs(success, R"({"errMsg":"enableAlertBeforeBackPage:ok"})");
1631 engine->CallJs(complete, R"({"errMsg":"enableAlertBeforeBackPage:ok"})");
1632 break;
1633 case 0:
1634 engine->CallJs(fail, R"({"errMsg":"enableAlertBeforeBackPage:fail cancel"})");
1635 engine->CallJs(complete, R"({"errMsg":"enableAlertBeforeBackPage:fail cancel"})");
1636 break;
1637 default:
1638 LOGE("callbackType is invalid");
1639 break;
1640 }
1641 };
1642 auto delegate = engine->GetFrontendDelegate();
1643 if (!delegate) {
1644 LOGE("EnableAlertBeforeBackPage failed. delegate is null.");
1645 return runtime->NewUndefined();
1646 }
1647 delegate->EnableAlertBeforeBackPage(message, std::move(callback));
1648 return runtime->NewUndefined();
1649 }
1650
DisableAlertBeforeBackPage(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1651 shared_ptr<JsValue> DisableAlertBeforeBackPage(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1652 {
1653 if (!runtime) {
1654 LOGE("DisableAlertBeforeBackPage failed. runtime is null.");
1655 return nullptr;
1656 }
1657 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1658 if (!engine) {
1659 LOGE("DisableAlertBeforeBackPage failed. engine is null.");
1660 return runtime->NewUndefined();
1661 }
1662 auto delegate = engine->GetFrontendDelegate();
1663 if (!delegate) {
1664 LOGE("DisableAlertBeforeBackPage failed. delegate is null.");
1665 return runtime->NewUndefined();
1666 }
1667 delegate->DisableAlertBeforeBackPage();
1668 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(arg->ToString(runtime));
1669 if (argsPtr->IsObject()) {
1670 const std::string success = JsParseRouteUrl(argsPtr, COMMON_SUCCESS);
1671 const std::string complete = JsParseRouteUrl(argsPtr, COMMON_COMPLETE);
1672 engine->CallJs(success, R"({"errMsg":"disableAlertBeforeBackPage:ok"})");
1673 engine->CallJs(complete, R"({"errMsg":"disableAlertBeforeBackPage:ok"})");
1674 return runtime->NewUndefined();
1675 }
1676
1677 std::string callBackStr = arg->ToString(runtime);
1678 // Get callbackId and clear redundant symbols, 2 is available min string length
1679 if (callBackStr.size() > 2 && callBackStr.front() == '\"' && callBackStr.back() == '\"') {
1680 callBackStr = callBackStr.substr(1, callBackStr.size() - 2);
1681 engine->CallJs(callBackStr, R"({"arguments":[{"errMsg":"disableAlertBeforeBackPage:ok"}],"method":"success"})");
1682 }
1683 return runtime->NewUndefined();
1684 }
1685
PostponePageTransition(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1686 shared_ptr<JsValue> PostponePageTransition(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1687 {
1688 if (!runtime) {
1689 LOGE("PostponePageTransition failed. runtime is null.");
1690 return nullptr;
1691 }
1692 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1693 if (!engine) {
1694 LOGE("PostponePageTransition failed. engine is null.");
1695 return runtime->NewUndefined();
1696 }
1697 auto delegate = engine->GetFrontendDelegate();
1698 if (!delegate) {
1699 LOGE("PostponePageTransition failed. delegate is null.");
1700 return runtime->NewUndefined();
1701 }
1702 delegate->PostponePageTransition();
1703 return runtime->NewUndefined();
1704 }
1705
LaunchPageTransition(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)1706 shared_ptr<JsValue> LaunchPageTransition(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
1707 {
1708 if (!runtime) {
1709 LOGE("LaunchPageTransition failed. runtime is null.");
1710 return nullptr;
1711 }
1712 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1713 if (!engine) {
1714 LOGE("LaunchPageTransition failed. engine is null.");
1715 return runtime->NewUndefined();
1716 }
1717 auto delegate = engine->GetFrontendDelegate();
1718 if (!delegate) {
1719 LOGE("LaunchPageTransition failed. delegate is null.");
1720 return runtime->NewUndefined();
1721 }
1722 delegate->LaunchPageTransition();
1723 return runtime->NewUndefined();
1724 }
1725
JsHandlePageRoute(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1726 shared_ptr<JsValue> JsHandlePageRoute(
1727 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1728 {
1729 std::string uri = "";
1730 if (methodName == ROUTE_PAGE_BACK) {
1731 uri = ParseRouteUrlSpecial(runtime, arg);
1732 } else {
1733 uri = ParseRouteUrl(runtime, arg, ROUTE_KEY_URI);
1734 }
1735 std::string params = ParseRouteParams(runtime, arg, ROUTE_KEY_PARAMS);
1736 bool dontOverwrite = ParseRouteOverwrite(runtime, arg, ROUTE_KEY_DONT_OVERWRITE);
1737
1738 std::unique_ptr<JsonValue> routerParamsData = JsonUtil::Create(true);
1739 routerParamsData->Put("paramsData", JsonUtil::ParseJsonString(params));
1740 routerParamsData->Put("dontOverwrite", dontOverwrite);
1741 params = routerParamsData->ToString();
1742
1743 auto engineInstance = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
1744 if (!engineInstance) {
1745 LOGE("engineInstance is null");
1746 return runtime->NewNull();
1747 }
1748 // Operator map for page route.
1749 static const LinearMapNode<shared_ptr<JsValue> (*)(const std::string&, const std::string&, JsiEngineInstance&)>
1750 pageRouteOperators[] = {
1751 { ROUTE_PAGE_BACK,
1752 [](const std::string& uri, const std::string& params, JsiEngineInstance& instance) {
1753 LOGD("JsBackRoute uri = %{private}s", uri.c_str());
1754 instance.GetFrontendDelegate()->Back(uri, params);
1755 return instance.GetJsRuntime()->NewNull();
1756 } },
1757 { ROUTE_PAGE_CLEAR,
1758 [](const std::string& uri, const std::string& params, JsiEngineInstance& instance) {
1759 LOGD("Clear Page Route");
1760 instance.GetFrontendDelegate()->Clear();
1761 return instance.GetJsRuntime()->NewNull();
1762 } },
1763 { ROUTE_PAGE_GET_LENGTH,
1764 [](const std::string& uri, const std::string& params, JsiEngineInstance& instance) {
1765 int32_t routeLength = instance.GetFrontendDelegate()->GetStackSize();
1766 std::string indexLength = std::to_string(routeLength);
1767 LOGD("JsGetLengthRoute routeLength=%{private}s", indexLength.c_str());
1768 return instance.GetJsRuntime()->NewString(indexLength);
1769 } },
1770 { ROUTE_PAGE_GET_STATE,
1771 [](const std::string& uri, const std::string& params, JsiEngineInstance& instance) {
1772 int32_t routeIndex = 0;
1773 std::string routeName;
1774 std::string routePath;
1775 instance.GetFrontendDelegate()->GetState(routeIndex, routeName, routePath);
1776 LOGD("JsGetStateRoute index=%{public}d name=%{private}s path=%{private}s", routeIndex,
1777 routeName.c_str(), routePath.c_str());
1778
1779 shared_ptr<JsRuntime> runtime = instance.GetJsRuntime();
1780 shared_ptr<JsValue> routeData = runtime->NewObject();
1781 routeData->SetProperty(runtime, "index", runtime->NewNumber(routeIndex));
1782 routeData->SetProperty(runtime, "name", runtime->NewString(routeName));
1783 routeData->SetProperty(runtime, "path", runtime->NewString(routePath));
1784 return routeData;
1785 } },
1786 { ROUTE_PAGE_PUSH,
1787 [](const std::string& uri, const std::string& params, JsiEngineInstance& instance) {
1788 LOGD("JsPushRoute uri = %{private}s", uri.c_str());
1789 instance.GetFrontendDelegate()->Push(uri, params);
1790 return instance.GetJsRuntime()->NewNull();
1791 } },
1792 { ROUTE_PAGE_REPLACE,
1793 [](const std::string& uri, const std::string& params, JsiEngineInstance& instance) {
1794 LOGD("JsReplaceRoute uri = %{private}s", uri.c_str());
1795 instance.GetFrontendDelegate()->Replace(uri, params);
1796 return instance.GetJsRuntime()->NewNull();
1797 } },
1798 };
1799 auto operatorIter = BinarySearchFindIndex(pageRouteOperators, ArraySize(pageRouteOperators), methodName.c_str());
1800 if (operatorIter != -1) {
1801 return pageRouteOperators[operatorIter].value(uri, params, *engineInstance);
1802 } else if (methodName == ROUTE_ENABLE_ALERT_BEFORE_BACK_PAGE) {
1803 return EnableAlertBeforeBackPage(runtime, arg);
1804 } else if (methodName == ROUTE_DISABLE_ALERT_BEFORE_BACK_PAGE) {
1805 return DisableAlertBeforeBackPage(runtime, arg);
1806 } else if (methodName == ROUTE_POSTPONE) {
1807 return PostponePageTransition(runtime, arg);
1808 } else if (methodName == ROUTE_LAUNCH) {
1809 return LaunchPageTransition(runtime, arg);
1810 } else {
1811 LOGW("system.router not support method = %{private}s", methodName.c_str());
1812 }
1813 return runtime->NewNull();
1814 }
1815
JsHandleSetTimeout(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1816 shared_ptr<JsValue> JsHandleSetTimeout(
1817 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1818 {
1819 if (methodName == SET_TIMEOUT) {
1820 SetTimer(runtime, arg, false);
1821 } else if (methodName == CLEAR_TIMEOUT || methodName == CLEAR_INTERVAL) {
1822 ClearTimeout(runtime, arg);
1823 } else if (methodName == SET_INTERVAL) {
1824 SetTimer(runtime, arg, true);
1825 } else {
1826 LOGW("Unsupported method for timer module!");
1827 }
1828 return runtime->NewNull();
1829 }
1830
JsHandleAnimator(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg,const std::string & methodName)1831 shared_ptr<JsValue> JsHandleAnimator(
1832 const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg, const std::string& methodName)
1833 {
1834 if (!runtime) {
1835 LOGE("runtime is nullptr");
1836 return nullptr;
1837 }
1838 if (!arg) {
1839 LOGE("arg is nullptr");
1840 runtime->ThrowError("Parameter error. The number of parameters must be greater than or equal to 1.",
1841 ERROR_CODE_PARAM_INVALID);
1842 return runtime->NewNull();
1843 }
1844 auto page = GetStagingPage(runtime);
1845 if (page == nullptr) {
1846 LOGE("page is nullptr");
1847 return runtime->NewNull();
1848 }
1849 std::string arguments = arg->ToString(runtime);
1850 // argv[1] is "1" when input null.
1851 if (arguments == "\"1\"") {
1852 runtime->ThrowError("Parameter error. The number of parameters must be greater than or equal to 1.",
1853 ERROR_CODE_PARAM_INVALID);
1854 return runtime->NewNull();
1855 }
1856 if (methodName == ANIMATOR_CREATE_ANIMATOR || methodName == ANIMATOR_CREATE) {
1857 int32_t bridgeId = JsiAnimatorBridgeUtils::JsCreateBridgeId();
1858 auto animatorContext = JsiAnimatorBridgeUtils::CreateAnimatorContext(runtime, page->GetPageId(), bridgeId);
1859 auto animatorBridge = AceType::MakeRefPtr<JsiAnimatorBridge>(runtime, animatorContext);
1860 auto task = AceType::MakeRefPtr<JsiAnimatorTaskCreate>(runtime, animatorBridge, arguments);
1861 page->PushCommand(Referenced::MakeRefPtr<JsCommandAnimator>(bridgeId, task));
1862 return animatorContext;
1863 }
1864 return runtime->NewNull();
1865 }
1866
JsHandleModule(const std::string & moduleName,const std::string & methodName,const shared_ptr<JsRuntime> & runtime,const std::vector<shared_ptr<JsValue>> & argv)1867 shared_ptr<JsValue> JsHandleModule(const std::string& moduleName, const std::string& methodName,
1868 const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv)
1869 {
1870 static const LinearMapNode<shared_ptr<JsValue> (*)(
1871 const shared_ptr<JsRuntime>&, const std::vector<shared_ptr<JsValue>>&, const std::string&)>
1872 jsHandleMap[] = {
1873 { "animation",
1874 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1875 const std::string& methodName) { return JsHandleAnimationFrame(runtime, argv[1], methodName); } },
1876 { "internal.jsResult",
1877 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1878 const std::string& methodName) { return JsHandleCallback(runtime, argv[1], methodName); } },
1879 { "ohos.animator",
1880 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1881 const std::string& methodName) { return JsHandleAnimator(runtime, argv[1], methodName); } },
1882 { "system.app",
1883 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1884 const std::string& methodName) { return JsHandleAppApi(runtime, argv[1], methodName); } },
1885 { "system.configuration",
1886 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1887 const std::string& methodName) { return JsCallConfiguration(runtime, argv[1], methodName); } },
1888 { "system.device",
1889 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1890 const std::string& methodName) {
1891 if (methodName == "getInfo") {
1892 return JsGetDeviceInfo(runtime, argv[1]);
1893 } else {
1894 return runtime->NewNull();
1895 }
1896 } },
1897 { "system.grid",
1898 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1899 const std::string& methodName) { return JsHandleGridLayout(runtime, argv[1], methodName); } },
1900 { "system.image", [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1901 const std::string& methodName) { return JsHandleImage(runtime, argv[1]); } },
1902 { "system.mediaquery",
1903 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1904 const std::string& methodName) { return JsHandleMediaQuery(runtime, argv[1], methodName); } },
1905 { "system.offscreenCanvas",
1906 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1907 const std::string& methodName) { return JsHandleOffscreenCanvas(runtime, argv[1], methodName); } },
1908 { "system.prompt",
1909 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1910 const std::string& methodName) { return JsHandlePrompt(runtime, argv[1], methodName); } },
1911 { "system.resource",
1912 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1913 const std::string& methodName) { return JsHandleReadResource(runtime, argv, methodName); } },
1914 { "system.router",
1915 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1916 const std::string& methodName) { return JsHandlePageRoute(runtime, argv[1], methodName); } },
1917 { "timer",
1918 [](const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
1919 const std::string& methodName) { return JsHandleSetTimeout(runtime, argv[1], methodName); } },
1920 };
1921
1922 auto jsHandleIter = BinarySearchFindIndex(jsHandleMap, ArraySize(jsHandleMap), moduleName.c_str());
1923 if (jsHandleIter != -1) {
1924 return jsHandleMap[jsHandleIter].value(runtime, std::move(argv), methodName);
1925 }
1926 return runtime->NewUndefined();
1927 }
1928
1929 // native implementation for js function: ace.domCreateBody()
JsDomCreateBody(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)1930 shared_ptr<JsValue> JsDomCreateBody(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
1931 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
1932 {
1933 if (argc != CREATE_BODY_ARGS_LEN) {
1934 LOGE("The arg is wrong, it is supposed to have %{public}d arguments", CREATE_BODY_ARGS_LEN);
1935 return runtime->NewUndefined();
1936 }
1937
1938 auto page = GetStagingPage(runtime);
1939 if (page == nullptr) {
1940 LOGE("GetStagingPage return nullptr");
1941 return runtime->NewUndefined();
1942 }
1943
1944 const int32_t pageId = page->GetPageId();
1945 int32_t nodeId = DOM_ROOT_NODE_ID_BASE + pageId;
1946 LOGD("JsDomCreateBody: pageId: %{public}d, nodeId: %{public}d:", pageId, nodeId);
1947
1948 std::string tag = argv[CREATE_BODY_TAG_IDX]->ToString(runtime);
1949 auto command = Referenced::MakeRefPtr<JsCommandCreateDomBody>(tag.c_str(), nodeId);
1950 SetDomAttributes(runtime, argv[CREATE_BODY_ATTR_IDX], *command);
1951 SetDomStyle(runtime, argv[CREATE_BODY_STYLE_IDX], *command);
1952 AddDomEvent(runtime, argv[CREATE_BODY_EVENT_IDX], *command);
1953 page->PushCommand(command);
1954 return runtime->NewUndefined();
1955 }
1956
JsDomAddElement(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)1957 shared_ptr<JsValue> JsDomAddElement(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
1958 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
1959 {
1960 if (argc != ADD_ELEMENT_ARGS_LEN) {
1961 LOGE("The argc is wrong, it is supposed to have %{public}d arguments", ADD_ELEMENT_ARGS_LEN);
1962 return runtime->NewUndefined();
1963 }
1964 auto page = GetStagingPage(runtime);
1965 if (page == nullptr) {
1966 LOGE("GetStagingPage return nullptr");
1967 return runtime->NewUndefined();
1968 }
1969
1970 const int32_t instanceId = argv[ADD_ELEMENT_INSTANCE_ID]->ToInt32(runtime);
1971 if (page->GetPageId() != instanceId) {
1972 page = GetFrontendDelegate(runtime)->GetPage(instanceId);
1973 if (page == nullptr) {
1974 LOGE("JsDomAddElement fail to get page, pageId: %{public}d", instanceId);
1975 return runtime->NewUndefined();
1976 }
1977 }
1978
1979 const int32_t pageId = page->GetPageId();
1980 int32_t parentNodeId = argv[ADD_ELEMENT_PARID_IDX]->ToInt32(runtime);
1981 parentNodeId = parentNodeId == 0 ? (DOM_ROOT_NODE_ID_BASE + pageId) : parentNodeId;
1982
1983 int32_t nodeId = argv[ADD_ELEMENT_NODEID_IDX]->ToInt32(runtime);
1984 std::string tag = argv[ADD_ELEMENT_TAG_IDX]->ToString(runtime);
1985 LOGD("JsDomAddElement: pageId: %{private}d, parentNodeId: %{private}d, nodeId: %{private}d, tag: %{private}s",
1986 pageId, parentNodeId, nodeId, tag.c_str());
1987
1988 auto command = Referenced::MakeRefPtr<JsCommandAddDomElement>(tag.c_str(), nodeId, parentNodeId);
1989 SetDomAttributes(runtime, argv[ADD_ELEMENT_ATTR_IDX], *command);
1990 SetDomStyle(runtime, argv[ADD_ELEMENT_STYLE_IDX], *command);
1991 AddDomEvent(runtime, argv[ADD_ELEMENT_EVENT_INDEX], *command);
1992 int32_t itemIndex = argv[ADD_ELEMENT_ITEM_INDEX]->ToInt32(runtime);
1993 if (argv[ADD_ELEMENT_CUSTOM_INDEX]->IsBoolean(runtime)) {
1994 bool isCustomComponent = argv[ADD_ELEMENT_CUSTOM_INDEX]->ToBoolean(runtime);
1995 command->SetIsCustomComponent(isCustomComponent);
1996 }
1997 command->SetForIndex(itemIndex);
1998 page->PushCommand(command);
1999 // Flush command as fragment immediately when pushed too many commands.
2000 if (!page->CheckPageCreated() && page->GetCommandSize() > FRAGMENT_SIZE) {
2001 page->FlushCommands();
2002 }
2003 return runtime->NewNull();
2004 }
2005
2006 // native implementation for js function: ace.removeElement()
JsRemoveElement(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2007 shared_ptr<JsValue> JsRemoveElement(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2008 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2009 {
2010 LOGD("JsRemoveElement");
2011 if (argc != REMOVE_ELEMENT_ARGS_LEN) {
2012 LOGE("The arg is wrong, it is supposed to have %{public}d arguments", REMOVE_ELEMENT_ARGS_LEN);
2013 return runtime->NewUndefined();
2014 }
2015
2016 auto page = GetStagingPage(runtime);
2017 if (page == nullptr) {
2018 LOGE("GetStagingPage return nullptr");
2019 return runtime->NewUndefined();
2020 }
2021
2022 const int32_t instanceId = argv[REMOVE_ELEMENT_INSTANCE_ID]->ToInt32(runtime);
2023 if (page->GetPageId() != instanceId) {
2024 page = GetFrontendDelegate(runtime)->GetPage(instanceId);
2025 if (page == nullptr) {
2026 LOGE("JsRemoveElement fail to get page, pageId: %{public}d", instanceId);
2027 return runtime->NewUndefined();
2028 }
2029 }
2030
2031 int32_t nodeId = argv[REMOVE_ELEMENT_ID_IDX]->ToInt32(runtime);
2032 nodeId = (nodeId == 0) ? DOM_ROOT_NODE_ID_BASE + page->GetPageId() : nodeId;
2033 page->PushCommand(Referenced::MakeRefPtr<JsCommandRemoveDomElement>(nodeId));
2034 return runtime->NewUndefined();
2035 }
2036
2037 // native implementation for js function: ace.updateElementAttrs()
JsUpdateElementAttrs(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2038 shared_ptr<JsValue> JsUpdateElementAttrs(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2039 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2040 {
2041 LOGD("JsUpdateElementAttrs");
2042 if (argc != UPLOAD_ELEMENT_ARGS_LEN) {
2043 LOGE("The arg is wrong, it is supposed to have %{public}d arguments", UPLOAD_ELEMENT_ARGS_LEN);
2044 return runtime->NewUndefined();
2045 }
2046
2047 auto page = GetStagingPage(runtime);
2048 if (page == nullptr) {
2049 LOGE("GetStagingPage return nullptr");
2050 return runtime->NewUndefined();
2051 }
2052
2053 const int32_t instanceId = argv[UPLOAD_ELEMENT_INSTANCE_ID]->ToInt32(runtime);
2054 if (page->GetPageId() != instanceId) {
2055 page = GetFrontendDelegate(runtime)->GetPage(instanceId);
2056 if (page == nullptr) {
2057 LOGE("JsRemoveElement fail to get page, pageId: %{public}d", instanceId);
2058 return runtime->NewUndefined();
2059 }
2060 }
2061
2062 int32_t nodeId = argv[UPLOAD_ELEMENT_NID_IDX]->ToInt32(runtime);
2063 nodeId = (nodeId == 0) ? DOM_ROOT_NODE_ID_BASE + page->GetPageId() : nodeId;
2064 auto command = Referenced::MakeRefPtr<JsCommandUpdateDomElementAttrs>(nodeId);
2065 if (SetDomAttributes(runtime, argv[UPLOAD_ELEMENT_DOM_IDX], *command)) {
2066 page->ReserveShowCommand(command);
2067 }
2068 page->PushCommand(command);
2069 return runtime->NewUndefined();
2070 }
2071
2072 // native implementation for js function: ace.updateElementStyles()
JsUpdateElementStyles(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2073 shared_ptr<JsValue> JsUpdateElementStyles(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2074 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2075 {
2076 LOGD("JsUpdateElementStyles");
2077 if (argc != UPLOAD_ELEMENT_ARGS_LEN) {
2078 LOGE("The arg is wrong, it is supposed to have %{public}d arguments", UPLOAD_ELEMENT_ARGS_LEN);
2079 return runtime->NewUndefined();
2080 }
2081
2082 auto page = GetStagingPage(runtime);
2083 if (page == nullptr) {
2084 LOGE("GetStagingPage return nullptr");
2085 return runtime->NewUndefined();
2086 }
2087
2088 const int32_t instanceId = argv[UPLOAD_ELEMENT_INSTANCE_ID]->ToInt32(runtime);
2089 if (page->GetPageId() != instanceId) {
2090 page = GetFrontendDelegate(runtime)->GetPage(instanceId);
2091 if (page == nullptr) {
2092 LOGE("JsRemoveElement fail to get page, pageId: %{public}d", instanceId);
2093 return runtime->NewUndefined();
2094 }
2095 }
2096
2097 int32_t nodeId = argv[UPLOAD_ELEMENT_NID_IDX]->ToInt32(runtime);
2098 nodeId = (nodeId == 0) ? DOM_ROOT_NODE_ID_BASE + page->GetPageId() : nodeId;
2099 auto command = Referenced::MakeRefPtr<JsCommandUpdateDomElementStyles>(nodeId);
2100 SetDomStyle(runtime, argv[UPLOAD_ELEMENT_DOM_IDX], *command);
2101 page->PushCommand(command);
2102 return runtime->NewUndefined();
2103 }
2104
2105 // native implementation for js function: ace.onCreateFinish()
JsOnCreateFinish(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2106 shared_ptr<JsValue> JsOnCreateFinish(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2107 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2108 {
2109 LOGD("JsOnCreateFinish");
2110
2111 auto page = GetStagingPage(runtime);
2112 if (page == nullptr) {
2113 LOGE("GetStagingPage return nullptr");
2114 return runtime->NewUndefined();
2115 }
2116
2117 page->SetPageCreated();
2118 return runtime->NewUndefined();
2119 }
2120
2121 // native implementation for js function: ace.onUpdateFinish()
JsOnUpdateFinish(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2122 shared_ptr<JsValue> JsOnUpdateFinish(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2123 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2124 {
2125 LOGD("JsOnUpdateFinish");
2126
2127 auto page = GetStagingPage(runtime);
2128 if (page == nullptr) {
2129 LOGE("GetStagingPage return nullptr");
2130 return runtime->NewUndefined();
2131 }
2132
2133 if (page->CheckPageCreated()) {
2134 GetFrontendDelegate(runtime)->TriggerPageUpdate(page->GetPageId());
2135 }
2136 return runtime->NewUndefined();
2137 }
2138
2139 // native implementation for js function: ace.callNative()
JsCallNative(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2140 shared_ptr<JsValue> JsCallNative(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2141 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2142 {
2143 LOGD("JsCallNative");
2144 if (argc != NATIVE_ARGS_LEN) {
2145 LOGE("The arg is wrong, it is supposed to have %{public}d arguments", NATIVE_ARGS_LEN);
2146 return runtime->NewUndefined();
2147 }
2148
2149 std::string moduleAndMethod = argv[NATIVE_ARGS_METHOD_IDX]->ToString(runtime);
2150 LOGD("JsCallNative moduleAndMethod = %{public}s", moduleAndMethod.c_str());
2151
2152 std::unique_ptr<JsonValue> moduleAndMethodPtr = JsonUtil::ParseJsonString(moduleAndMethod);
2153 if (!moduleAndMethodPtr) {
2154 LOGE("Get moduleAndMethod from argv failed");
2155 return runtime->NewUndefined();
2156 }
2157
2158 std::unique_ptr<JsonValue> modulePtr = moduleAndMethodPtr->GetValue("module");
2159 if (!modulePtr) {
2160 LOGE("Get module from moduleAndMethodPtr failed");
2161 return runtime->NewUndefined();
2162 }
2163
2164 std::unique_ptr<JsonValue> methodPtr = moduleAndMethodPtr->GetValue("method");
2165 if (!methodPtr) {
2166 LOGE("Get method from moduleAndMethodPtr failed");
2167 return runtime->NewUndefined();
2168 }
2169
2170 const std::string moduleName = modulePtr->GetString();
2171 const std::string methodName = methodPtr->GetString();
2172
2173 return JsHandleModule(moduleName, methodName, runtime, argv);
2174 }
2175
2176 // native implementation for js function: ace.callComponent()
JsCallComponent(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2177 shared_ptr<JsValue> JsCallComponent(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2178 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2179 {
2180 LOGD("JsCallComponent");
2181 if (argc != COMPONENT_ARGS_LEN) {
2182 LOGE("The arg is wrong, it is supposed to have %{public}d arguments", COMPONENT_ARGS_LEN);
2183 return runtime->NewUndefined();
2184 }
2185
2186 auto page = GetRunningPage(runtime);
2187 if (page == nullptr) {
2188 return runtime->NewUndefined();
2189 }
2190 int32_t nodeId = argv[COMPONENT_ARGS_ID_IDX]->ToInt32(runtime);
2191 nodeId = (nodeId == 0) ? DOM_ROOT_NODE_ID_BASE + page->GetPageId() : nodeId;
2192 std::string methodName = argv[COMPONENT_ARGS_METHOD_IDX]->ToString(runtime);
2193 std::string arguments = argv[COMPONENT_ARGS_IDX]->ToString(runtime);
2194
2195 if (std::strcmp(methodName.c_str(), "getContext") == 0) {
2196 auto canvasBridge = AceType::DynamicCast<JsiCanvasBridge>(page->GetBridgeById(nodeId));
2197 if (canvasBridge) {
2198 canvasBridge->HandleJsContext(runtime, nodeId, arguments);
2199 return canvasBridge->GetRenderContext();
2200 }
2201 return runtime->NewUndefined();
2202 } else if (std::strcmp(methodName.c_str(), "toDataURL") == 0) {
2203 auto bridge = AceType::DynamicCast<JsiCanvasBridge>(page->GetBridgeById(nodeId));
2204 if (bridge) {
2205 bridge->HandleToDataURL(runtime, nodeId, arguments);
2206 return bridge->GetDataURL();
2207 }
2208 } else if (std::strcmp(methodName.c_str(), "getBoundingClientRect") == 0) {
2209 return JsiComponentApiBridge::JsGetBoundingRect(runtime, nodeId);
2210 } else if (std::strcmp(methodName.c_str(), "getInspector") == 0) {
2211 return JsiComponentApiBridge::JsGetInspector(runtime, nodeId);
2212 } else if (std::strcmp(methodName.c_str(), "getScrollOffset") == 0) {
2213 return JsiComponentApiBridge::JsGetScrollOffset(runtime, nodeId);
2214 } else if (std::strcmp(methodName.c_str(), "scrollTo") == 0) {
2215 JsiComponentApiBridge::JsScrollTo(runtime, arguments, nodeId);
2216 return runtime->NewUndefined();
2217 } else if (std::strcmp(methodName.c_str(), "getXComponentContext") == 0) {
2218 #ifdef XCOMPONENT_SUPPORTED
2219 auto bridge = AceType::DynamicCast<JsiXComponentBridge>(page->GetXComponentBridgeById(nodeId));
2220 if (bridge) {
2221 bridge->HandleContext(runtime, nodeId, arguments);
2222 return bridge->GetRenderContext();
2223 }
2224 return runtime->NewUndefined();
2225 } else if (std::strcmp(methodName.c_str(), "getXComponentSurfaceId") == 0) {
2226 return JsiXComponentBridge::JsGetXComponentSurfaceId(runtime, nodeId);
2227 } else if (std::strcmp(methodName.c_str(), "setXComponentSurfaceSize") == 0) {
2228 JsiXComponentBridge::JsSetXComponentSurfaceSize(runtime, arguments, nodeId);
2229 return runtime->NewUndefined();
2230 #endif
2231 }
2232
2233 shared_ptr<JsValue> resultValue = runtime->NewUndefined();
2234 if (std::strcmp(methodName.c_str(), "animate") == 0) {
2235 LOGD("animate args = %{private}s", arguments.c_str());
2236 resultValue = JsiAnimationBridgeUtils::CreateAnimationContext(runtime, page->GetPageId(), nodeId);
2237 auto animationBridge = AceType::MakeRefPtr<JsiAnimationBridge>(runtime, resultValue, nodeId);
2238 auto task = AceType::MakeRefPtr<JsiAnimationBridgeTaskCreate>(runtime, animationBridge, arguments);
2239 page->PushCommand(Referenced::MakeRefPtr<JsCommandAnimation>(nodeId, task));
2240 } else if (std::strcmp(methodName.c_str(), "currentOffset") == 0) {
2241 return JsiListBridge::JsGetCurrentOffset(runtime, nodeId);
2242 } else if (std::strcmp(methodName.c_str(), "getState") == 0) {
2243 return JsiImageAnimatorBridge::JsGetState(runtime, nodeId);
2244 } else if (std::strcmp(methodName.c_str(), "addChild") == 0) {
2245 auto sPage = GetStagingPage(runtime);
2246 if (sPage == nullptr) {
2247 return runtime->NewUndefined();
2248 }
2249 int32_t childNodeId = 0;
2250 std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(arguments);
2251 if (argsValue && argsValue->IsArray()) {
2252 std::unique_ptr<JsonValue> cNodeId = argsValue->GetArrayItem(0)->GetValue("__nodeId");
2253 if (cNodeId && cNodeId->IsNumber()) {
2254 childNodeId = cNodeId->GetInt();
2255 }
2256 }
2257 auto domDocument = sPage->GetDomDocument();
2258 if (domDocument) {
2259 RefPtr<DOMNode> node = domDocument->GetDOMNodeById(childNodeId);
2260 if (node == nullptr) {
2261 LOGE("node is nullptr");
2262 }
2263 auto command = Referenced::MakeRefPtr<JsCommandAppendElement>(node ? node->GetTag() : "", childNodeId,
2264 nodeId);
2265 sPage->PushCommand(command);
2266 if (!sPage->CheckPageCreated() && sPage->GetCommandSize() > FRAGMENT_SIZE) {
2267 sPage->FlushCommands();
2268 }
2269 }
2270 return runtime->NewUndefined();
2271 } else {
2272 page->PushCommand(Referenced::MakeRefPtr<JsCommandCallDomElementMethod>(nodeId, methodName, arguments));
2273 }
2274 // focus method should delayed util show attribute update.
2275 if (page->CheckPageCreated() && strlen(DOM_FOCUS) >= strlen(methodName.c_str()) &&
2276 strcmp(DOM_FOCUS, methodName.c_str()) != 0) {
2277 GetFrontendDelegate(runtime)->TriggerPageUpdate(page->GetPageId(), true);
2278 }
2279 return resultValue;
2280 }
2281
GetNodeId(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & arg)2282 int GetNodeId(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& arg)
2283 {
2284 int32_t id = 0;
2285 auto nodeId = arg->GetProperty(runtime, "__nodeId");
2286 if (nodeId && nodeId->IsInt32(runtime)) {
2287 id = nodeId->ToInt32(runtime);
2288 }
2289 id = id < 0 ? 0 : id;
2290 return id;
2291 }
2292
AppClearData(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2293 std::shared_ptr<JsValue> AppClearData(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2294 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2295 {
2296 if (!clipboard) {
2297 auto pipelineContext = GetFrontendDelegate(runtime)->GetPipelineContext();
2298 clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipelineContext->GetTaskExecutor());
2299 }
2300 auto page = GetStagingPage(runtime);
2301 if (page == nullptr) {
2302 LOGE("page is nullptr");
2303 return runtime->NewUndefined();
2304 }
2305 if (argv.empty() || argc == 0) {
2306 if (JsiEngineInstance::dataMap_.size() > 0) {
2307 JsiEngineInstance::dataMap_.clear();
2308 clipboard->SetData("");
2309 return runtime->NewBoolean(true);
2310 }
2311 }
2312 if (JsiEngineInstance::dataMap_.count(argv[0]->ToString(runtime)) == 1) {
2313 JsiEngineInstance::dataMap_.erase(argv[0]->ToString(runtime));
2314 std::string strResult;
2315 strResult.append("{");
2316 std::map<const std::string, std::string>::iterator iter = JsiEngineInstance::dataMap_.begin();
2317 while (iter != JsiEngineInstance::dataMap_.end()) {
2318 std::string key = iter->first;
2319 std::string val = iter->second;
2320 strResult.append("\"")
2321 .append(key)
2322 .append("\":")
2323 .append(val);
2324 ++iter;
2325 if (iter != JsiEngineInstance::dataMap_.end()) {
2326 strResult.append(",");
2327 }
2328 }
2329 strResult.append("}");
2330 clipboard->SetData(strResult);
2331 return runtime->NewBoolean(true);
2332 }
2333 return runtime->NewBoolean(false);
2334 }
2335
AppSetData(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2336 shared_ptr<JsValue> AppSetData(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2337 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2338 {
2339 if (!clipboard) {
2340 auto pipelineContext = GetFrontendDelegate(runtime)->GetPipelineContext();
2341 clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipelineContext->GetTaskExecutor());
2342 }
2343 auto page = GetStagingPage(runtime);
2344 if (page == nullptr) {
2345 LOGE("page is nullptr");
2346 return runtime->NewUndefined();
2347 }
2348 if (argv.empty() || argc != 2) {
2349 return runtime->NewBoolean(false);
2350 }
2351 JsiEngineInstance::dataMap_[argv[0]->ToString(runtime)] = argv[1]->GetJsonString(runtime);
2352
2353 std::string strResult;
2354 strResult.append("{");
2355 std::map<const std::string, std::string>::iterator iter = JsiEngineInstance::dataMap_.begin();
2356 while (iter != JsiEngineInstance::dataMap_.end()) {
2357 std::string key = iter->first;
2358 std::string val = iter->second;
2359 strResult.append("\"").append(key).append("\":").append(val);
2360 ++iter;
2361 if (iter != JsiEngineInstance::dataMap_.end()) {
2362 strResult.append(",");
2363 }
2364 }
2365 strResult.append("}");
2366 clipboard->SetData(strResult);
2367 return runtime->NewBoolean(true);
2368 }
2369
AppGetData(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2370 shared_ptr<JsValue> AppGetData(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2371 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2372 {
2373 if (!clipboard) {
2374 auto pipelineContext = GetFrontendDelegate(runtime)->GetPipelineContext();
2375 clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipelineContext->GetTaskExecutor());
2376 }
2377 auto page = GetStagingPage(runtime);
2378 if (page == nullptr) {
2379 LOGE("page is nullptr");
2380 return runtime->NewUndefined();
2381 }
2382 if (argv.empty() || argc == 0) {
2383 LOGE("argc = 0");
2384 return runtime->NewBoolean(false);
2385 }
2386 std::string clipData;
2387 std::string* clipDataPtr = &clipData;
2388 std::string key = argv[0]->ToString(runtime);
2389 auto callback = [key, clipDataPtr](const std::string& data) {
2390 auto clipboardObj = JsonUtil::ParseJsonString(data);
2391 auto value = clipboardObj->GetValue(key);
2392 if (value) {
2393 *clipDataPtr = value->ToString();
2394 }
2395 };
2396 clipboard->GetData(callback, true);
2397 return runtime->ParseJson(clipData);
2398 }
2399
AppSetDataImage(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2400 shared_ptr<JsValue> AppSetDataImage(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2401 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2402 {
2403 auto page = GetStagingPage(runtime);
2404 if (page == nullptr) {
2405 LOGE("page is nullptr");
2406 return runtime->NewUndefined();
2407 }
2408 if (argv.empty() || argc != 3) {
2409 return runtime->NewBoolean(false);
2410 }
2411 #if !defined(PREVIEW)
2412 DOMDocument::pixelMap_ = CreatePixelMapFromNapiValue(runtime, argv[0]);
2413 if (argv[1] && argv[1]->IsInt32(runtime)) {
2414 DOMDocument::pixelMapOffsetX_ = argv[1]->ToInt32(runtime);
2415 }
2416 if (argv[2] && argv[2]->IsInt32(runtime)) {
2417 DOMDocument::pixelMapOffsetY_ = argv[2]->ToInt32(runtime);
2418 }
2419 if (!DOMDocument::pixelMap_) {
2420 return runtime->NewUndefined();
2421 }
2422 #endif
2423 return runtime->NewUndefined();
2424 }
2425
JsSetAttribute(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2426 shared_ptr<JsValue> JsSetAttribute(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2427 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2428 {
2429 if (argc != 2) {
2430 LOGE("the argc is error");
2431 return runtime->NewUndefined();
2432 }
2433 auto page = GetStagingPage(runtime);
2434 if (page == nullptr) {
2435 LOGE("GetStagingPage return nullptr");
2436 return runtime->NewUndefined();
2437 }
2438 if (!argv[0]->IsString(runtime) || !argv[1]->IsString(runtime)) {
2439 LOGE("args is not string ");
2440 return runtime->NewUndefined();
2441 }
2442 shared_ptr<JsValue> attr = runtime->NewObject();
2443 attr->SetProperty(runtime, argv[0], argv[1]);
2444
2445 int32_t nodeId = GetNodeId(runtime, thisObj);
2446 auto command = Referenced::MakeRefPtr<JsCommandUpdateDomElementAttrs>(nodeId);
2447 if (SetDomAttributes(runtime, attr, *command)) {
2448 page->ReserveShowCommand(command);
2449 }
2450 page->PushCommand(command);
2451 return runtime->NewUndefined();
2452 }
2453
JsSetStyle(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2454 shared_ptr<JsValue> JsSetStyle(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2455 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2456 {
2457 if (argc != 2) {
2458 LOGE("the argc is error");
2459 return runtime->NewBoolean(false);
2460 }
2461 auto page = GetStagingPage(runtime);
2462 if (page == nullptr) {
2463 LOGE("GetStagingPage return nullptr");
2464 return runtime->NewBoolean(false);
2465 }
2466 if (!argv[0]->IsString(runtime) || !argv[1]->IsString(runtime)) {
2467 LOGE("args is not string ");
2468 return runtime->NewBoolean(false);
2469 }
2470 shared_ptr<JsValue> style = runtime->NewObject();
2471 style->SetProperty(runtime, argv[0], argv[1]);
2472
2473 int32_t nodeId = GetNodeId(runtime, thisObj);
2474 auto command = Referenced::MakeRefPtr<JsCommandUpdateDomElementStyles>(nodeId);
2475 SetDomStyle(runtime, style, *command);
2476 page->PushCommand(command);
2477 return runtime->NewBoolean(true);
2478 }
2479
JsAppendChild(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2480 shared_ptr<JsValue> JsAppendChild(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2481 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2482 {
2483 auto page = GetStagingPage(runtime);
2484 if (page == nullptr) {
2485 LOGE("page is nullptr");
2486 return runtime->NewUndefined();
2487 }
2488 int32_t id = GetNodeId(runtime, argv[0]);
2489 auto domDocument = page->GetDomDocument();
2490 if (domDocument) {
2491 RefPtr<DOMNode> node = domDocument->GetDOMNodeById(id);
2492 if (node == nullptr) {
2493 LOGE("node is nullptr");
2494 }
2495 int32_t parentNodeId = GetNodeId(runtime, thisObj);
2496 RefPtr<DOMNode> parentNode = domDocument->GetDOMNodeById(parentNodeId);
2497 if (parentNode == nullptr) {
2498 LOGE("parentNodeId is nullptr");
2499 }
2500 if (parentNode != nullptr && node != nullptr) {
2501 parentNode->RemoveNode(node);
2502 }
2503 auto command = Referenced::MakeRefPtr<JsCommandAppendElement>(node ? node->GetTag() : "", id, parentNodeId);
2504 page->PushCommand(command);
2505 if (!page->CheckPageCreated() && page->GetCommandSize() > FRAGMENT_SIZE) {
2506 page->FlushCommands();
2507 }
2508 }
2509 return runtime->NewUndefined();
2510 }
2511
CreateDomElement(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2512 int32_t CreateDomElement(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2513 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2514 {
2515 if (argc != 1) {
2516 LOGE("the argc is error");
2517 return -1;
2518 }
2519 auto page = GetStagingPage(runtime);
2520 if (page == nullptr) {
2521 LOGE("GetStagingPage return nullptr");
2522 return -1;
2523 }
2524 int32_t nodeId = ++globalNodeId;
2525 std::string tag = argv[0]->ToString(runtime);
2526 auto command = Referenced::MakeRefPtr<JsCommandCreateDomElement>(tag.c_str(), nodeId);
2527 page->PushCommand(command);
2528 if (!page->CheckPageCreated() && page->GetCommandSize() > FRAGMENT_SIZE) {
2529 page->FlushCommands();
2530 }
2531 return globalNodeId;
2532 }
2533
JsFocus(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2534 shared_ptr<JsValue> JsFocus(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2535 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2536 {
2537 auto page = GetStagingPage(runtime);
2538 if (page == nullptr) {
2539 LOGE("page is nullptr");
2540 return runtime->NewUndefined();
2541 }
2542 if (page->CheckPageCreated()) {
2543 GetFrontendDelegate(runtime)->TriggerPageUpdate(page->GetPageId(), true);
2544 }
2545 return runtime->NewUndefined();
2546 }
2547
JsAnimate(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2548 shared_ptr<JsValue> JsAnimate(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2549 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2550 {
2551 auto page = GetStagingPage(runtime);
2552 if (page == nullptr) {
2553 LOGE("page is nullptr");
2554 return runtime->NewUndefined();
2555 }
2556 int32_t nodeId = GetNodeId(runtime, thisObj);
2557 std::string arguments = argv[0]->ToString(runtime);
2558 shared_ptr<JsValue> resultValue = runtime->NewUndefined();
2559 resultValue = JsiAnimationBridgeUtils::CreateAnimationContext(runtime, page->GetPageId(), nodeId);
2560 auto animationBridge = AceType::MakeRefPtr<JsiAnimationBridge>(runtime, resultValue, nodeId);
2561 auto task = AceType::MakeRefPtr<JsiAnimationBridgeTaskCreate>(runtime, animationBridge, arguments);
2562 page->PushCommand(Referenced::MakeRefPtr<JsCommandAnimation>(nodeId, task));
2563 return runtime->NewUndefined();
2564 }
2565
JsGetBoundingClientRect(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2566 shared_ptr<JsValue> JsGetBoundingClientRect(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2567 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2568 {
2569 int32_t nodeId = GetNodeId(runtime, thisObj);
2570 return JsiComponentApiBridge::JsGetBoundingRect(runtime, nodeId);
2571 }
2572
JsGetInspector(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2573 shared_ptr<JsValue> JsGetInspector(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2574 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2575 {
2576 int32_t nodeId = GetNodeId(runtime, thisObj);
2577 return JsiComponentApiBridge::JsGetInspector(runtime, nodeId);
2578 }
2579
JsCreateElement(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2580 shared_ptr<JsValue> JsCreateElement(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2581 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2582 {
2583 int32_t newNodeId = CreateDomElement(runtime, thisObj, argv, argc);
2584 shared_ptr<JsValue> node = runtime->NewObject();
2585 node->SetProperty(runtime, "__nodeId", runtime->NewInt32(newNodeId));
2586 node->SetProperty(runtime, "setAttribute", runtime->NewFunction(JsSetAttribute));
2587 node->SetProperty(runtime, "setStyle", runtime->NewFunction(JsSetStyle));
2588 node->SetProperty(runtime, "addChild", runtime->NewFunction(JsAppendChild));
2589 node->SetProperty(runtime, "focus", runtime->NewFunction(JsFocus));
2590 node->SetProperty(runtime, "animate", runtime->NewFunction(JsAnimate));
2591 node->SetProperty(runtime, "getBoundingClientRect", runtime->NewFunction(JsGetBoundingClientRect));
2592 node->SetProperty(runtime, "getInspector", runtime->NewFunction(JsGetInspector));
2593 return node;
2594 }
2595
2596 // native implementation for js function: perfutil.print()
JsPerfPrint(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2597 shared_ptr<JsValue> JsPerfPrint(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2598 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2599 {
2600 std::string ret = JsApiPerf::GetInstance().PrintToLogs();
2601 return runtime->NewString(ret);
2602 }
2603
2604 // native implementation for js function: perfutil.sleep()
JsPerfSleep(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2605 shared_ptr<JsValue> JsPerfSleep(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2606 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2607 {
2608 int32_t valInt = argv[0]->ToInt32(runtime);
2609 usleep(valInt);
2610 return runtime->NewNull();
2611 }
2612
2613 // native implementation for js function: perfutil.begin()
JsPerfBegin(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2614 shared_ptr<JsValue> JsPerfBegin(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2615 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2616 {
2617 int64_t currentTime = GetMicroTickCount();
2618 JsApiPerf::GetInstance().InsertJsBeginLog(argv[0]->ToString(runtime), currentTime);
2619 return runtime->NewNull();
2620 }
2621
2622 // native implementation for js function: perfutil.end()
JsPerfEnd(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2623 shared_ptr<JsValue> JsPerfEnd(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2624 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2625 {
2626 int64_t currentTime = GetMicroTickCount();
2627 JsApiPerf::GetInstance().InsertJsEndLog(argv[0]->ToString(runtime), currentTime);
2628 return runtime->NewNull();
2629 }
2630
2631 // native implementation for js function: hiView.report()
JsHiViewReport(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2632 shared_ptr<JsValue> JsHiViewReport(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2633 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2634 {
2635 LOGD("JsHiViewReport");
2636
2637 if (argc != HIVIEW_ARGS_LEN) {
2638 LOGE("argc error, argc = %{public}d", argc);
2639 return runtime->NewNull();
2640 }
2641 if (argv[HIVIEW_ARGS_ID_IDX]->IsNumber(runtime) && argv[HIVIEW_ARGS_JSON_IDX]->IsString(runtime)) {
2642 std::string eventId = argv[HIVIEW_ARGS_ID_IDX]->ToString(runtime);
2643 std::string eventJson = argv[HIVIEW_ARGS_JSON_IDX]->ToString(runtime);
2644 EventReport::JsEventReport(StringToInt(eventId), eventJson);
2645 LOGD("JsEventReport success");
2646 } else {
2647 LOGE("parameter type error");
2648 }
2649 return runtime->NewNull();
2650 }
2651
2652 // native implementation for js function: i18nPluralRules.select()
JsPluralRulesFormat(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2653 shared_ptr<JsValue> JsPluralRulesFormat(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2654 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2655 {
2656 // Should have one parameters.
2657 if (argc != 1) {
2658 LOGE("argc error, argc = %{public}d", argc);
2659 return runtime->NewNull();
2660 }
2661 if (argv[0]->IsNumber(runtime)) {
2662 std::string choice = argv[0]->ToString(runtime);
2663 shared_ptr<JsValue> result =
2664 runtime->NewString(Localization::GetInstance()->PluralRulesFormat(StringToDouble(choice)));
2665 return result;
2666 } else {
2667 LOGE("parameter type error ");
2668 return runtime->NewNull();
2669 }
2670 }
2671
2672 // -----------------------
2673 // Start JsiEngineInstance
2674 // -----------------------
~JsiEngineInstance()2675 JsiEngineInstance::~JsiEngineInstance()
2676 {
2677 // Destroy group bridge
2678 auto groupJsBridge = frontendDelegate_->GetGroupJsBridge();
2679 if (groupJsBridge != nullptr) {
2680 groupJsBridge->Destroy();
2681 }
2682
2683 if (runningPage_) {
2684 runningPage_->OnJsEngineDestroy();
2685 }
2686
2687 if (stagingPage_) {
2688 stagingPage_->OnJsEngineDestroy();
2689 }
2690
2691 if (runtime_) {
2692 runtime_->RegisterUncaughtExceptionHandler(nullptr);
2693 runtime_->Reset();
2694 }
2695 runtime_.reset();
2696 runtime_ = nullptr;
2697 }
2698
FlushCommandBuffer(void * context,const std::string & command)2699 void JsiEngineInstance::FlushCommandBuffer(void* context, const std::string& command)
2700 {
2701 // These js code is put into jsfwk, No need to do any thing here.
2702 return;
2703 }
2704
GetJsRuntime() const2705 shared_ptr<JsRuntime> JsiEngineInstance::GetJsRuntime() const
2706 {
2707 return runtime_;
2708 }
2709
GetRunningPage() const2710 RefPtr<JsAcePage> JsiEngineInstance::GetRunningPage() const
2711 {
2712 std::lock_guard<std::mutex> lock(mutex_);
2713 return runningPage_;
2714 }
2715
GetStagingPage() const2716 RefPtr<JsAcePage> JsiEngineInstance::GetStagingPage() const
2717 {
2718 std::lock_guard<std::mutex> lock(mutex_);
2719 return stagingPage_;
2720 }
2721
GetJsMessageDispatcher() const2722 WeakPtr<JsMessageDispatcher> JsiEngineInstance::GetJsMessageDispatcher() const
2723 {
2724 return dispatcher_;
2725 }
2726
GetFrontendDelegate() const2727 RefPtr<FrontendDelegate> JsiEngineInstance::GetFrontendDelegate() const
2728 {
2729 return frontendDelegate_;
2730 }
2731
SetRunningPage(const RefPtr<JsAcePage> & page)2732 void JsiEngineInstance::SetRunningPage(const RefPtr<JsAcePage>& page)
2733 {
2734 std::lock_guard<std::mutex> lock(mutex_);
2735 runningPage_ = page;
2736 }
2737
SetStagingPage(const RefPtr<JsAcePage> & page)2738 void JsiEngineInstance::SetStagingPage(const RefPtr<JsAcePage>& page)
2739 {
2740 std::lock_guard<std::mutex> lock(mutex_);
2741 stagingPage_ = page;
2742 }
2743
ResetStagingPage(const RefPtr<JsAcePage> & page)2744 void JsiEngineInstance::ResetStagingPage(const RefPtr<JsAcePage>& page)
2745 {
2746 std::lock_guard<std::mutex> lock(mutex_);
2747 stagingPage_ = page;
2748 }
2749
SetJsMessageDispatcher(const WeakPtr<JsMessageDispatcher> & dispatcher)2750 void JsiEngineInstance::SetJsMessageDispatcher(const WeakPtr<JsMessageDispatcher>& dispatcher)
2751 {
2752 dispatcher_ = dispatcher;
2753 }
2754
RegisterAceModule()2755 void JsiEngineInstance::RegisterAceModule()
2756 {
2757 ACE_SCOPED_TRACE("JsiEngine::RegisterAceModule");
2758 LOGD("JsiEngineInstance RegisterAceModule");
2759
2760 shared_ptr<JsValue> aceObj = runtime_->NewObject();
2761 if (!aceObj) {
2762 LOGE("RegisterAceModule failed. aceObj is null");
2763 return;
2764 }
2765 if (!aceObj->SetProperty(runtime_, "domCreateBody", runtime_->NewFunction(JsDomCreateBody))) {
2766 LOGE("RegisterAceModule domCreateBody failed.");
2767 }
2768 if (!aceObj->SetProperty(runtime_, "domAddElement", runtime_->NewFunction(JsDomAddElement))) {
2769 LOGE("RegisterAceModule domAddElement failed.");
2770 }
2771 if (!aceObj->SetProperty(runtime_, "removeElement", runtime_->NewFunction(JsRemoveElement))) {
2772 LOGE("RegisterAceModule removeElement failed.");
2773 }
2774 if (!aceObj->SetProperty(runtime_, "updateElementAttrs", runtime_->NewFunction(JsUpdateElementAttrs))) {
2775 LOGE("RegisterAceModule updateElementAttrs failed.");
2776 }
2777 if (!aceObj->SetProperty(runtime_, "updateElementStyles", runtime_->NewFunction(JsUpdateElementStyles))) {
2778 LOGE("RegisterAceModule updateElementStyles failed.");
2779 }
2780 if (!aceObj->SetProperty(runtime_, "onCreateFinish", runtime_->NewFunction(JsOnCreateFinish))) {
2781 LOGE("RegisterAceModule onCreateFinish failed.");
2782 }
2783 if (!aceObj->SetProperty(runtime_, "onUpdateFinish", runtime_->NewFunction(JsOnUpdateFinish))) {
2784 LOGE("RegisterAceModule onUpdateFinish failed.");
2785 }
2786 if (!aceObj->SetProperty(runtime_, "callNative", runtime_->NewFunction(JsCallNative))) {
2787 LOGE("RegisterAceModule callNative failed.");
2788 }
2789 if (!aceObj->SetProperty(runtime_, "callComponent", runtime_->NewFunction(JsCallComponent))) {
2790 LOGE("RegisterAceModule callComponent failed.");
2791 }
2792
2793 shared_ptr<JsValue> global = runtime_->GetGlobal();
2794 if (!global->SetProperty(runtime_, "ace", aceObj)) {
2795 LOGE("RegisterAceModule ace failed.");
2796 }
2797 }
2798
JsCallNativeHandler(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2799 shared_ptr<JsValue> JsCallNativeHandler(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2800 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2801 {
2802 if (argc != 2 || !argv[0]->IsString(runtime) || !argv[1]->IsString(runtime)) {
2803 LOGE("JsCallNativeHandler: invalid parameters");
2804 return runtime->NewNull();
2805 }
2806
2807 auto engine = static_cast<JsiEngineInstance*>(runtime->GetEmbedderData());
2808 if (engine == nullptr) {
2809 return runtime->NewNull();
2810 }
2811
2812 std::string event = argv[0]->ToString(runtime);
2813 std::string params = argv[1]->ToString(runtime);
2814 engine->GetDelegate()->CallNativeHandler(event, params);
2815 return runtime->NewNull();
2816 }
2817
RegisterConsoleModule()2818 void JsiEngineInstance::RegisterConsoleModule()
2819 {
2820 ACE_SCOPED_TRACE("JsiEngine::RegisterConsoleModule");
2821 LOGD("JsiEngineInstance RegisterConsoleModule");
2822 shared_ptr<JsValue> global = runtime_->GetGlobal();
2823
2824 // app log method
2825 shared_ptr<JsValue> consoleObj = runtime_->NewObject();
2826 consoleObj->SetProperty(runtime_, "log", runtime_->NewFunction(JsiBaseUtils::AppInfoLogPrint));
2827 consoleObj->SetProperty(runtime_, "debug", runtime_->NewFunction(JsiBaseUtils::AppDebugLogPrint));
2828 consoleObj->SetProperty(runtime_, "info", runtime_->NewFunction(JsiBaseUtils::AppInfoLogPrint));
2829 consoleObj->SetProperty(runtime_, "warn", runtime_->NewFunction(JsiBaseUtils::AppWarnLogPrint));
2830 consoleObj->SetProperty(runtime_, "error", runtime_->NewFunction(JsiBaseUtils::AppErrorLogPrint));
2831 global->SetProperty(runtime_, "console", consoleObj);
2832
2833 // js framework log method
2834 shared_ptr<JsValue> aceConsoleObj = runtime_->NewObject();
2835 aceConsoleObj->SetProperty(runtime_, "log", runtime_->NewFunction(JsiBaseUtils::JsInfoLogPrint));
2836 aceConsoleObj->SetProperty(runtime_, "debug", runtime_->NewFunction(JsiBaseUtils::JsDebugLogPrint));
2837 aceConsoleObj->SetProperty(runtime_, "info", runtime_->NewFunction(JsiBaseUtils::JsInfoLogPrint));
2838 aceConsoleObj->SetProperty(runtime_, "warn", runtime_->NewFunction(JsiBaseUtils::JsWarnLogPrint));
2839 aceConsoleObj->SetProperty(runtime_, "error", runtime_->NewFunction(JsiBaseUtils::JsErrorLogPrint));
2840 global->SetProperty(runtime_, "aceConsole", aceConsoleObj);
2841 global->SetProperty(runtime_, "callNativeHandler", runtime_->NewFunction(JsCallNativeHandler));
2842 }
2843
RegisterConsoleModule(ArkNativeEngine * engine)2844 void JsiEngineInstance::RegisterConsoleModule(ArkNativeEngine* engine)
2845 {
2846 ACE_SCOPED_TRACE("JsiEngineInstance::RegisterConsoleModule");
2847 LOGD("JsiEngineInstance RegisterConsoleModule to nativeEngine");
2848 NativeValue* global = engine->GetGlobal();
2849 if (global->TypeOf() != NATIVE_OBJECT) {
2850 LOGE("global is not NativeObject");
2851 return;
2852 }
2853 auto nativeGlobal = reinterpret_cast<NativeObject*>(global->GetInterface(NativeObject::INTERFACE_ID));
2854
2855 // app log method
2856 NativeValue* console = engine->CreateObject();
2857 auto consoleObj = reinterpret_cast<NativeObject*>(console->GetInterface(NativeObject::INTERFACE_ID));
2858 consoleObj->SetProperty("log", engine->CreateFunction("log", strlen("log"), AppInfoLogPrint, nullptr));
2859 consoleObj->SetProperty("debug", engine->CreateFunction("debug", strlen("debug"), AppDebugLogPrint, nullptr));
2860 consoleObj->SetProperty("info", engine->CreateFunction("info", strlen("info"), AppInfoLogPrint, nullptr));
2861 consoleObj->SetProperty("warn", engine->CreateFunction("warn", strlen("warn"), AppWarnLogPrint, nullptr));
2862 consoleObj->SetProperty("error", engine->CreateFunction("error", strlen("error"), AppErrorLogPrint, nullptr));
2863 nativeGlobal->SetProperty("console", console);
2864 }
2865
SyscapCanIUse(const shared_ptr<JsRuntime> & runtime,const shared_ptr<JsValue> & thisObj,const std::vector<shared_ptr<JsValue>> & argv,int32_t argc)2866 shared_ptr<JsValue> SyscapCanIUse(const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& thisObj,
2867 const std::vector<shared_ptr<JsValue>>& argv, int32_t argc)
2868 {
2869 if (argc != 1) {
2870 LOGE("argc should be 1");
2871 return runtime->NewNull();
2872 }
2873 if (!argv[0]->IsString(runtime)) {
2874 LOGW("argv[0] is not IsString");
2875 return runtime->NewNull();
2876 }
2877
2878 std::string syscapString = argv[0]->ToString(runtime);
2879 bool ret = Ace::SystemProperties::IsSyscapExist(syscapString.c_str());
2880 return runtime->NewBoolean(ret);
2881 }
2882
RegisterSyscapModule()2883 void JsiEngineInstance::RegisterSyscapModule()
2884 {
2885 ACE_SCOPED_TRACE("JsiEngine::RegisterSyscapModule");
2886 LOGD("JsiEngineInstance RegisterSyscapModule");
2887 shared_ptr<JsValue> global = runtime_->GetGlobal();
2888
2889 global->SetProperty(runtime_, CAN_IUSE, runtime_->NewFunction(SyscapCanIUse));
2890 }
2891
RegisterDocumentModule()2892 void JsiEngineInstance::RegisterDocumentModule()
2893 {
2894 ACE_SCOPED_TRACE("JsiEngine::RegisterDocumentModule");
2895 LOGD("JsiEngineInstance RegisterDocumentModule");
2896 shared_ptr<JsValue> global = runtime_->GetGlobal();
2897 shared_ptr<JsValue> domObj = runtime_->NewObject();
2898 domObj->SetProperty(runtime_, "createElement", runtime_->NewFunction(JsCreateElement));
2899 global->SetProperty(runtime_, "dom", domObj);
2900 }
2901
RegisterPerfUtilModule()2902 void JsiEngineInstance::RegisterPerfUtilModule()
2903 {
2904 ACE_SCOPED_TRACE("JsiEngine::RegisterPerfUtilModule");
2905 LOGD("JsiEngineInstance RegisterPerfUtilModule");
2906 shared_ptr<JsValue> perfObj = runtime_->NewObject();
2907 perfObj->SetProperty(runtime_, "printlog", runtime_->NewFunction(JsPerfPrint));
2908 perfObj->SetProperty(runtime_, "sleep", runtime_->NewFunction(JsPerfSleep));
2909 perfObj->SetProperty(runtime_, "begin", runtime_->NewFunction(JsPerfBegin));
2910 perfObj->SetProperty(runtime_, "end", runtime_->NewFunction(JsPerfEnd));
2911
2912 shared_ptr<JsValue> global = runtime_->GetGlobal();
2913 global->SetProperty(runtime_, "perfutil", perfObj);
2914 }
2915
RegisterHiViewModule()2916 void JsiEngineInstance::RegisterHiViewModule()
2917 {
2918 ACE_SCOPED_TRACE("JsiEngine::RegisterHiViewModule");
2919 LOGD("JsiEngineInstance RegisterHiViewModule");
2920 shared_ptr<JsValue> hiViewObj = runtime_->NewObject();
2921 hiViewObj->SetProperty(runtime_, "report", runtime_->NewFunction(JsHiViewReport));
2922
2923 shared_ptr<JsValue> global = runtime_->GetGlobal();
2924 global->SetProperty(runtime_, "hiView", hiViewObj);
2925 }
2926
RegisterI18nPluralRulesModule()2927 void JsiEngineInstance::RegisterI18nPluralRulesModule()
2928 {
2929 ACE_SCOPED_TRACE("JsiEngine::RegisterI18nPluralRulesModule");
2930 LOGD("JsiEngineInstance RegisterI18nPluralRulesModule");
2931 shared_ptr<JsValue> i18nObj = runtime_->NewObject();
2932 i18nObj->SetProperty(runtime_, "select", runtime_->NewFunction(JsPluralRulesFormat));
2933
2934 shared_ptr<JsValue> global = runtime_->GetGlobal();
2935 global->SetProperty(runtime_, "i18nPluralRules", i18nObj);
2936 }
2937
RegisterFaPlugin()2938 void JsiEngineInstance::RegisterFaPlugin()
2939 {
2940 shared_ptr<JsValue> global = runtime_->GetGlobal();
2941 shared_ptr<JsValue> requireNapiFunc = global->GetProperty(runtime_, "requireNapi");
2942 if (!requireNapiFunc || !requireNapiFunc->IsFunction(runtime_)) {
2943 LOGW("requireNapi func not found");
2944 return;
2945 }
2946 std::vector<shared_ptr<JsValue>> argv = { runtime_->NewString("FeatureAbility") };
2947 requireNapiFunc->Call(runtime_, global, argv, argv.size());
2948 }
2949
InitJsEnv(bool debugger_mode,const std::unordered_map<std::string,void * > & extraNativeObject)2950 bool JsiEngineInstance::InitJsEnv(bool debugger_mode, const std::unordered_map<std::string, void*>& extraNativeObject)
2951 {
2952 ACE_SCOPED_TRACE("JsiEngine::InitJsEnv");
2953 runtime_.reset(new ArkJSRuntime());
2954 if (runtime_ == nullptr) {
2955 LOGE("Js Engine cannot allocate JSI JSRuntime");
2956 EventReport::SendJsException(JsExcepType::JS_ENGINE_INIT_ERR);
2957 return false;
2958 }
2959
2960 runtime_->SetLogPrint(PrintLog);
2961 std::string library_path = "";
2962 if (debugger_mode) {
2963 SetDebuggerPostTask(library_path);
2964 }
2965 if (!runtime_->Initialize(library_path, isDebugMode_, GetInstanceId())) {
2966 LOGE("Js Engine initialize runtime failed");
2967 return false;
2968 }
2969
2970 #if !defined(PREVIEW)
2971 for (const auto& [key, value] : extraNativeObject) {
2972 shared_ptr<JsValue> nativeValue = runtime_->NewNativePointer(value);
2973 runtime_->GetGlobal()->SetProperty(runtime_, key, nativeValue);
2974 }
2975
2976 runtime_->StartDebugger();
2977 #endif
2978
2979 RegisterAceModule();
2980 RegisterConsoleModule();
2981 RegisterSyscapModule();
2982 RegisterDocumentModule();
2983 RegisterPerfUtilModule();
2984 RegisterHiViewModule();
2985 RegisterI18nPluralRulesModule();
2986
2987 // load jsfwk
2988 #ifdef OHOS_PLATFORM
2989 if (!runtime_->ExecuteJsBin("/system/etc/strip.native.min.abc")) {
2990 LOGE("Failed to load js framework!");
2991 return false;
2992 }
2993 #else
2994 bool jsfwkResult = runtime_->EvaluateJsCode((uint8_t*)_binary_strip_native_min_abc_start,
2995 _binary_strip_native_min_abc_end - _binary_strip_native_min_abc_start);
2996 if (!jsfwkResult) {
2997 LOGE("Failed to load js framework!");
2998 return false;
2999 }
3000 #endif
3001 LOGD("Load js framework success");
3002
3003 // Init groupJsBridge
3004 InitGroupJsBridge();
3005
3006 runtime_->SetEmbedderData(this);
3007 runtime_->RegisterUncaughtExceptionHandler(JsiBaseUtils::ReportJsErrorEvent);
3008 return true;
3009 }
3010
InitGroupJsBridge()3011 void JsiEngineInstance::InitGroupJsBridge()
3012 {
3013 auto groupJsBridge = DynamicCast<JsiGroupJsBridge>(frontendDelegate_->GetGroupJsBridge());
3014 if (groupJsBridge == nullptr || groupJsBridge->InitializeGroupJsBridge(runtime_) == JS_CALL_FAIL) {
3015 LOGE("Js Engine Initialize GroupJsBridge failed!");
3016 EventReport::SendJsException(JsExcepType::JS_ENGINE_INIT_ERR);
3017 }
3018 }
3019
FireJsEvent(const std::string & eventStr)3020 bool JsiEngineInstance::FireJsEvent(const std::string& eventStr)
3021 {
3022 LOGD("JsiEngineInstance FireJsEvent");
3023 if (!runningPage_) {
3024 LOGW("js engine instance running page is not valid.");
3025 return false;
3026 }
3027 std::vector<shared_ptr<JsValue>> argv;
3028 argv.push_back(runtime_->NewString(std::to_string(runningPage_->GetPageId())));
3029 shared_ptr<JsValue> var1 = runtime_->ParseJson(eventStr);
3030 if (var1->IsArray(runtime_)) {
3031 shared_ptr<JsValue> varArray = var1->GetProperty(runtime_, 0);
3032 if (varArray->IsObject(runtime_)) {
3033 shared_ptr<JsValue> args = varArray->GetProperty(runtime_, "args");
3034 if (args->IsArray(runtime_)) {
3035 shared_ptr<JsValue> stdDrag = args->GetProperty(runtime_, 1);
3036 if (IsDragEvent(stdDrag->GetJsonString(runtime_))) {
3037 shared_ptr<JsValue> arrayType = args->GetProperty(runtime_, 2);
3038 if (arrayType->IsObject(runtime_)) {
3039 shared_ptr<JsValue> dataTransfer = runtime_->NewObject();
3040 dataTransfer->SetProperty(runtime_, "clearData", runtime_->NewFunction(AppClearData));
3041 dataTransfer->SetProperty(runtime_, "getData", runtime_->NewFunction(AppGetData));
3042 dataTransfer->SetProperty(runtime_, "setData", runtime_->NewFunction(AppSetData));
3043 dataTransfer->SetProperty(runtime_, "setDragImage", runtime_->NewFunction(AppSetDataImage));
3044 arrayType->SetProperty(runtime_, "dataTransfer", dataTransfer);
3045 }
3046 }
3047 }
3048 }
3049 }
3050 argv.push_back(var1);
3051
3052 shared_ptr<JsValue> global = runtime_->GetGlobal();
3053 shared_ptr<JsValue> func = global->GetProperty(runtime_, "callJS");
3054
3055 if (!func->IsFunction(runtime_)) {
3056 LOGE("\"callJs\" is not a function!");
3057 return false;
3058 }
3059 func->Call(runtime_, global, argv, argv.size());
3060 return true;
3061 }
3062
IsDragEvent(const std::string & param)3063 bool JsiEngineInstance::IsDragEvent(const std::string& param)
3064 {
3065 std::string::size_type idx = param.find("drag");
3066 return !(idx == std::string::npos);
3067 }
3068
CallJs(const std::string & callbackId,const std::string & args,bool keepAlive,bool isGlobal)3069 void JsiEngineInstance::CallJs(const std::string& callbackId, const std::string& args, bool keepAlive, bool isGlobal)
3070 {
3071 std::string keepAliveStr = keepAlive ? "true" : "false";
3072 std::string callBuff = std::string("[{\"args\": [\"")
3073 .append(callbackId)
3074 .append("\",")
3075 .append(args)
3076 .append(",")
3077 .append(keepAliveStr)
3078 .append("], \"method\":\"callback\"}]");
3079 LOGD("CallJs string: %{private}s", callBuff.c_str());
3080 int32_t instanceId = isGlobal ? DEFAULT_APP_ID : runningPage_->GetPageId();
3081
3082 std::vector<shared_ptr<JsValue>> argv;
3083 argv.push_back(runtime_->NewString(std::to_string(instanceId)));
3084 argv.push_back(runtime_->ParseJson(callBuff));
3085
3086 shared_ptr<JsValue> global = runtime_->GetGlobal();
3087 shared_ptr<JsValue> func = global->GetProperty(runtime_, "callJS");
3088 if (!func->IsFunction(runtime_)) {
3089 LOGE("\"callJs\" is not a function!");
3090 return;
3091 }
3092 func->Call(runtime_, global, argv, argv.size());
3093 }
3094
3095 #if defined(PREVIEW)
CallCurlFunction(const OHOS::Ace::RequestData & requestData,int32_t callbackId)3096 bool JsiEngineInstance::CallCurlFunction(const OHOS::Ace::RequestData& requestData, int32_t callbackId)
3097 {
3098 auto dispatcher = dispatcher_.Upgrade();
3099 if (dispatcher) {
3100 dispatcher->CallCurlFunction(requestData, callbackId);
3101 return true;
3102 } else {
3103 LOGW("Dispatcher Upgrade fail when dispatch request message to platform");
3104 return false;
3105 }
3106 }
3107 #endif
3108
SetDebuggerPostTask(std::string & library_path)3109 void JsiEngineInstance::SetDebuggerPostTask(std::string& library_path)
3110 {
3111 library_path = ARK_DEBUGGER_LIB_PATH;
3112 auto weakDelegate = AceType::WeakClaim(AceType::RawPtr(frontendDelegate_));
3113 auto&& postTask = [weakDelegate](std::function<void()>&& task) {
3114 auto delegate = weakDelegate.Upgrade();
3115 if (delegate == nullptr) {
3116 LOGE("delegate is nullptr");
3117 return;
3118 }
3119 delegate->PostJsTask(std::move(task));
3120 };
3121 std::static_pointer_cast<ArkJSRuntime>(runtime_)->SetDebuggerPostTask(postTask);
3122 }
3123
3124 // -----------------------
3125 // Start JsiEngine
3126 // -----------------------
Initialize(const RefPtr<FrontendDelegate> & delegate)3127 bool JsiEngine::Initialize(const RefPtr<FrontendDelegate>& delegate)
3128 {
3129 ACE_SCOPED_TRACE("JsiEngine::Initialize");
3130 LOGD("JsiEngine initialize");
3131 engineInstance_ = AceType::MakeRefPtr<JsiEngineInstance>(delegate, instanceId_);
3132 engineInstance_->SetDebugMode(NeedDebugBreakPoint());
3133 bool result = engineInstance_->InitJsEnv(IsDebugVersion(), GetExtraNativeObject());
3134 if (!result) {
3135 LOGE("JsiEngine Initialize, init js env failed");
3136 return false;
3137 }
3138
3139 auto runtime = engineInstance_->GetJsRuntime();
3140 auto vm = std::static_pointer_cast<ArkJSRuntime>(runtime)->GetEcmaVm();
3141 if (vm == nullptr) {
3142 LOGE("JsiEngine Initialize, vm is null");
3143 return false;
3144 }
3145
3146 auto nativeEngine = new ArkNativeEngine(const_cast<EcmaVM*>(vm), static_cast<void*>(this));
3147 nativeEngine_ = nativeEngine;
3148 engineInstance_->SetNativeEngine(nativeEngine_);
3149 SetPostTask(nativeEngine_);
3150 #if !defined(PREVIEW)
3151 nativeEngine_->CheckUVLoop();
3152 #endif
3153
3154 ACE_DCHECK(delegate);
3155 if (delegate && delegate->GetAssetManager()) {
3156 std::vector<std::string> packagePath = delegate->GetAssetManager()->GetLibPath();
3157 auto appLibPathKey = delegate->GetAssetManager()->GetAppLibPathKey();
3158 if (!packagePath.empty()) {
3159 nativeEngine->SetPackagePath(appLibPathKey, packagePath);
3160 }
3161 }
3162 engineInstance_->RegisterFaPlugin();
3163 RegisterWorker();
3164
3165 return true;
3166 }
3167
SetPostTask(NativeEngine * nativeEngine)3168 void JsiEngine::SetPostTask(NativeEngine* nativeEngine)
3169 {
3170 auto weakDelegate = AceType::WeakClaim(AceType::RawPtr(engineInstance_->GetDelegate()));
3171 auto&& postTask = [weakDelegate, weakEngine = AceType::WeakClaim(this), id = instanceId_](bool needSync) {
3172 auto delegate = weakDelegate.Upgrade();
3173 if (delegate == nullptr) {
3174 LOGE("delegate is nullptr");
3175 return;
3176 }
3177
3178 delegate->PostJsTask([weakEngine, needSync, id]() {
3179 auto jsEngine = weakEngine.Upgrade();
3180 if (jsEngine == nullptr) {
3181 LOGW("jsEngine is nullptr");
3182 return;
3183 }
3184 auto nativeEngine = jsEngine->GetNativeEngine();
3185 if (nativeEngine == nullptr) {
3186 return;
3187 }
3188 ContainerScope scope(id);
3189 nativeEngine->Loop(LOOP_NOWAIT, needSync);
3190 });
3191 };
3192 nativeEngine_->SetPostTask(postTask);
3193 }
3194
RegisterInitWorkerFunc()3195 void JsiEngine::RegisterInitWorkerFunc()
3196 {
3197 auto weakInstance = AceType::WeakClaim(AceType::RawPtr(engineInstance_));
3198 bool debugVersion = IsDebugVersion();
3199 bool debugMode = NeedDebugBreakPoint();
3200 std::string libraryPath = "";
3201 if (debugVersion) {
3202 libraryPath = ARK_DEBUGGER_LIB_PATH;
3203 }
3204 auto&& initWorkerFunc = [weakInstance, debugMode, libraryPath](NativeEngine* nativeEngine) {
3205 LOGI("WorkerCore RegisterInitWorkerFunc called");
3206 if (nativeEngine == nullptr) {
3207 LOGE("nativeEngine is nullptr");
3208 return;
3209 }
3210 auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine);
3211 if (arkNativeEngine == nullptr) {
3212 LOGE("arkNativeEngine is nullptr");
3213 return;
3214 }
3215 auto instance = weakInstance.Upgrade();
3216 if (instance == nullptr) {
3217 LOGE("instance is nullptr");
3218 return;
3219 }
3220 #ifdef OHOS_PLATFORM
3221 ConnectServerManager::Get().AddInstance(gettid());
3222 auto vm = const_cast<EcmaVM*>(arkNativeEngine->GetEcmaVm());
3223 auto workerPostTask = [nativeEngine](std::function<void()>&& callback) {
3224 nativeEngine->CallDebuggerPostTaskFunc(std::move(callback));
3225 };
3226 panda::JSNApi::StartDebugger(libraryPath.c_str(), vm, debugMode, gettid(), workerPostTask);
3227 #endif
3228 instance->RegisterConsoleModule(arkNativeEngine);
3229 // load jsfwk
3230 if (!arkNativeEngine->ExecuteJsBin("/system/etc/strip.native.min.abc")) {
3231 LOGE("Failed to load js framework!");
3232 }
3233 };
3234 nativeEngine_->SetInitWorkerFunc(initWorkerFunc);
3235 }
3236
3237 #ifdef OHOS_PLATFORM
RegisterOffWorkerFunc()3238 void JsiEngine::RegisterOffWorkerFunc()
3239 {
3240 auto weakInstance = AceType::WeakClaim(AceType::RawPtr(engineInstance_));
3241 bool debugVersion = IsDebugVersion();
3242 auto&& offWorkerFunc = [debugVersion](NativeEngine* nativeEngine) {
3243 LOGI("WorkerCore RegisterOffWorkerFunc called");
3244 if (!debugVersion) {
3245 return;
3246 }
3247 if (nativeEngine == nullptr) {
3248 LOGE("nativeEngine is nullptr");
3249 return;
3250 }
3251 auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine);
3252 if (arkNativeEngine == nullptr) {
3253 LOGE("arkNativeEngine is nullptr");
3254 return;
3255 }
3256 ConnectServerManager::Get().RemoveInstance(gettid());
3257 auto vm = const_cast<EcmaVM*>(arkNativeEngine->GetEcmaVm());
3258 panda::JSNApi::StopDebugger(vm);
3259 };
3260 nativeEngine_->SetOffWorkerFunc(offWorkerFunc);
3261 }
3262 #endif
3263
RegisterAssetFunc()3264 void JsiEngine::RegisterAssetFunc()
3265 {
3266 auto weakDelegate = AceType::WeakClaim(AceType::RawPtr(engineInstance_->GetDelegate()));
3267 auto&& assetFunc = [weakDelegate](const std::string& uri, std::vector<uint8_t>& content, std::string& ami) {
3268 LOGI("WorkerCore RegisterAssetFunc called");
3269 auto delegate = weakDelegate.Upgrade();
3270 if (delegate == nullptr) {
3271 LOGE("delegate is nullptr");
3272 return;
3273 }
3274 size_t index = uri.find_last_of(".");
3275 if (index == std::string::npos) {
3276 LOGE("invalid uri");
3277 } else {
3278 delegate->GetResourceData(uri.substr(0, index) + ".abc", content, ami);
3279 }
3280 };
3281 nativeEngine_->SetGetAssetFunc(assetFunc);
3282 }
3283
RegisterWorker()3284 void JsiEngine::RegisterWorker()
3285 {
3286 RegisterInitWorkerFunc();
3287 #ifdef OHOS_PLATFORM
3288 RegisterOffWorkerFunc();
3289 #endif
3290 RegisterAssetFunc();
3291 }
3292
~JsiEngine()3293 JsiEngine::~JsiEngine()
3294 {
3295 LOG_DESTROY();
3296 if (nativeEngine_ != nullptr) {
3297 #if !defined(PREVIEW)
3298 nativeEngine_->CancelCheckUVLoop();
3299 #endif
3300 nativeEngine_->DeleteEngine();
3301 delete nativeEngine_;
3302 nativeEngine_ = nullptr;
3303 }
3304 if (engineInstance_) {
3305 engineInstance_->SetNativeEngine(nullptr);
3306 }
3307 }
3308
GetLoadOptions(std::string & optionStr,bool isMainPage,bool hasAppCode)3309 void JsiEngine::GetLoadOptions(std::string& optionStr, bool isMainPage, bool hasAppCode)
3310 {
3311 LOGD("JsiEngine GetLoadOptions");
3312 ACE_DCHECK(engineInstance_);
3313 auto delegate = engineInstance_->GetFrontendDelegate();
3314 if (!delegate) {
3315 LOGW("GetLoadOptions error: delegate is null");
3316 return;
3317 }
3318 auto mediaQuery = delegate->GetMediaQueryInfoInstance();
3319 auto renderOption = MediaQueryInfo::GetMediaQueryJsonInfo();
3320 if (mediaQuery) {
3321 renderOption->Put("isInit", mediaQuery->GetIsInit());
3322 }
3323 renderOption->Put("pcPreview", PC_PREVIEW);
3324 renderOption->Put("appInstanceId", "10002");
3325 renderOption->Put("packageName", delegate->GetAppID().c_str());
3326
3327 // get resoureConfig
3328 delegate->GetResourceConfiguration(renderOption);
3329
3330 // get i18n message
3331 delegate->GetI18nData(renderOption);
3332 std::string language = AceApplicationInfo::GetInstance().GetLanguage();
3333 std::string region = AceApplicationInfo::GetInstance().GetCountryOrRegion();
3334 std::string local = language + "_" + region;
3335 renderOption->Put("language", local.c_str());
3336
3337 if (isMainPage && hasAppCode) {
3338 renderOption->Put("appCreate", "true");
3339 } else {
3340 renderOption->Put("appCreate", "false");
3341 }
3342 optionStr = renderOption->ToString();
3343 }
3344
ExecuteAbc(const std::string & fileName)3345 bool JsiEngine::ExecuteAbc(const std::string &fileName)
3346 {
3347 auto runtime = engineInstance_->GetJsRuntime();
3348 auto delegate = engineInstance_->GetDelegate();
3349
3350 std::vector<uint8_t> content;
3351 if (!delegate->GetAssetContent(fileName, content)) {
3352 LOGD("GetAssetContent \"%{private}s\" failed.", fileName.c_str());
3353 return true;
3354 }
3355 #ifdef OHOS_PLATFORM
3356 const std::string abcPath = delegate->GetAssetPath(fileName).append(fileName);
3357 #else
3358 const std::string& abcPath = fileName;
3359 #endif
3360 if (!runtime->EvaluateJsCode(content.data(), content.size(), abcPath)) {
3361 LOGE("EvaluateJsCode \"%{private}s\" failed.", fileName.c_str());
3362 return false;
3363 }
3364 return true;
3365 }
3366
LoadJs(const std::string & url,const RefPtr<JsAcePage> & page,bool isMainPage)3367 void JsiEngine::LoadJs(const std::string& url, const RefPtr<JsAcePage>& page, bool isMainPage)
3368 {
3369 ACE_SCOPED_TRACE("JsiEngine::LoadJs");
3370 LOGD("JsiEngine LoadJs");
3371 ACE_DCHECK(engineInstance_);
3372 engineInstance_->SetStagingPage(page);
3373 if (isMainPage) {
3374 ACE_DCHECK(!engineInstance_->GetRunningPage());
3375 engineInstance_->SetRunningPage(page);
3376 }
3377
3378 auto runtime = engineInstance_->GetJsRuntime();
3379 auto delegate = engineInstance_->GetFrontendDelegate();
3380
3381 // get source map
3382 std::string jsSourceMap;
3383 if (delegate->GetAssetContent(url + ".map", jsSourceMap)) {
3384 page->SetPageMap(jsSourceMap);
3385 } else {
3386 LOGI("js source map load failed!");
3387 }
3388 // get js bundle content
3389 shared_ptr<JsValue> jsCode = runtime->NewUndefined();
3390 shared_ptr<JsValue> jsAppCode = runtime->NewUndefined();
3391 const char js_ext[] = ".js";
3392 const char bin_ext[] = ".abc";
3393 auto pos = url.rfind(js_ext);
3394 if (pos != std::string::npos && pos == url.length() - (sizeof(js_ext) - 1)) {
3395 std::string urlName = url.substr(0, pos) + bin_ext;
3396
3397 if (isMainPage) {
3398 if (!ExecuteAbc("commons.abc")) {
3399 return;
3400 }
3401 if (!ExecuteAbc("vendors.abc")) {
3402 return;
3403 }
3404 std::string appMap;
3405 if (delegate->GetAssetContent("app.js.map", appMap)) {
3406 page->SetAppMap(appMap);
3407 } else {
3408 LOGI("app map load failed!");
3409 }
3410 if (!ExecuteAbc("app.abc")) {
3411 LOGE("ExecuteJsBin \"app.js\" failed.");
3412 return;
3413 }
3414 jsAppCode = runtime->GetGlobal()->GetProperty(runtime, "___mainEntry___");
3415 runtime->GetGlobal()->SetProperty(runtime, "___mainEntry___", runtime->NewUndefined());
3416 if (!jsAppCode->IsFunction(runtime)) {
3417 LOGE("appJsCode is not a function");
3418 return;
3419 }
3420 }
3421 if (!ExecuteAbc(urlName)) {
3422 return;
3423 }
3424
3425 jsCode = runtime->GetGlobal()->GetProperty(runtime, "___mainEntry___");
3426 runtime->GetGlobal()->SetProperty(runtime, "___mainEntry___", runtime->NewUndefined());
3427 if (!jsCode->IsFunction(runtime)) {
3428 LOGE("jsCode is not a function");
3429 return;
3430 }
3431 }
3432
3433 // get page params
3434 std::string jsonData = page->GetPageParams();
3435 if (jsonData.empty()) {
3436 jsonData = "{}";
3437 }
3438
3439 // get load options
3440 std::string optionStr;
3441 GetLoadOptions(optionStr, isMainPage, jsAppCode->IsFunction(runtime));
3442 shared_ptr<JsValue> instanceId = runtime->NewString(std::to_string(page->GetPageId()));
3443 shared_ptr<JsValue> renderOptions = runtime->ParseJson(optionStr);
3444 if (isMainPage && (!renderOptions || !renderOptions->SetProperty(runtime, "appCode", jsAppCode))) {
3445 LOGE("appCode property set failed.");
3446 return;
3447 }
3448 shared_ptr<JsValue> data = runtime->ParseJson(jsonData);
3449 shared_ptr<JsValue> info = runtime->NewObject();
3450 const std::vector<shared_ptr<JsValue>>& argv = { instanceId, jsCode, renderOptions, data, info };
3451
3452 shared_ptr<JsValue> global = runtime->GetGlobal();
3453 shared_ptr<JsValue> func = global->GetProperty(runtime, "createInstance");
3454
3455 if (!func) {
3456 LOGE("\"createInstance\" not found");
3457 return;
3458 }
3459 if (!func->IsFunction(runtime)) {
3460 LOGE("\"createInstance\" is not a function");
3461 return;
3462 }
3463
3464 func->Call(runtime, global, argv, argv.size());
3465 }
3466
3467 // Update running page
UpdateRunningPage(const RefPtr<JsAcePage> & page)3468 void JsiEngine::UpdateRunningPage(const RefPtr<JsAcePage>& page)
3469 {
3470 LOGD("JsiEngine UpdateRunningPage");
3471 ACE_DCHECK(engineInstance_);
3472 engineInstance_->SetRunningPage(page);
3473 }
3474
3475 // Update staging page
UpdateStagingPage(const RefPtr<JsAcePage> & page)3476 void JsiEngine::UpdateStagingPage(const RefPtr<JsAcePage>& page)
3477 {
3478 LOGD("JsiEngine UpdateStagingPage");
3479 ACE_DCHECK(engineInstance_);
3480 engineInstance_->SetStagingPage(page);
3481 }
3482
3483 // Reset loading page
ResetStagingPage()3484 void JsiEngine::ResetStagingPage()
3485 {
3486 LOGD("JsiEngine ResetStagingPage");
3487 ACE_DCHECK(engineInstance_);
3488 // weird
3489 auto runningPage = engineInstance_->GetRunningPage();
3490 engineInstance_->ResetStagingPage(runningPage);
3491 }
3492
SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher> & dispatcher)3493 void JsiEngine::SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher>& dispatcher)
3494 {
3495 LOGD("JsiEngine SetJsMessageDispatcher");
3496 ACE_DCHECK(engineInstance_);
3497 engineInstance_->SetJsMessageDispatcher(dispatcher);
3498 }
3499
FireAsyncEvent(const std::string & eventId,const std::string & param)3500 void JsiEngine::FireAsyncEvent(const std::string& eventId, const std::string& param)
3501 {
3502 LOGD("JsiEngine FireAsyncEvent");
3503 ACE_DCHECK(engineInstance_);
3504
3505 std::string callBuf = std::string("[{\"args\": [\"")
3506 .append(eventId)
3507 .append("\",")
3508 .append(param)
3509 .append("], \"method\":\"fireEvent\"}]");
3510 LOGD("FireASyncEvent string: %{private}s", callBuf.c_str());
3511
3512 ACE_DCHECK(engineInstance_);
3513 if (!engineInstance_->FireJsEvent(callBuf.c_str())) {
3514 LOGE("Js Engine FireSyncEvent FAILED!");
3515 }
3516 }
3517
FireSyncEvent(const std::string & eventId,const std::string & param)3518 void JsiEngine::FireSyncEvent(const std::string& eventId, const std::string& param)
3519 {
3520 LOGD("JsiEngine FireSyncEvent");
3521 std::string callBuf = std::string("[{\"args\": [\"")
3522 .append(eventId)
3523 .append("\",")
3524 .append(param)
3525 .append("], \"method\":\"fireEventSync\"}]");
3526 LOGD("FireSyncEvent string: %{private}s", callBuf.c_str());
3527
3528 ACE_DCHECK(engineInstance_);
3529 if (!engineInstance_->FireJsEvent(callBuf.c_str())) {
3530 LOGE("Js Engine FireSyncEvent FAILED!");
3531 }
3532 }
3533
FireExternalEvent(const std::string & componentId,const uint32_t nodeId,const bool isDestroy)3534 void JsiEngine::FireExternalEvent(const std::string& componentId, const uint32_t nodeId, const bool isDestroy)
3535 {
3536 ACE_DCHECK(engineInstance_);
3537 if (isDestroy) {
3538 return;
3539 }
3540 auto runtime = engineInstance_->GetJsRuntime();
3541 auto page = GetRunningPage(runtime);
3542 if (page == nullptr) {
3543 LOGE("FireExternalEvent GetRunningPage is nullptr");
3544 return;
3545 }
3546 #ifdef XCOMPONENT_SUPPORTED
3547 std::string arguments;
3548 auto bridge = AceType::DynamicCast<JsiXComponentBridge>(page->GetXComponentBridgeById(nodeId));
3549 if (bridge) {
3550 bridge->HandleContext(runtime, nodeId, arguments);
3551 return;
3552 }
3553 #endif
3554 }
3555
3556 // Destroy page instance on Js
DestroyPageInstance(int32_t pageId)3557 void JsiEngine::DestroyPageInstance(int32_t pageId)
3558 {
3559 LOGI("JsiEngine DestroyPageInstance");
3560 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3561 const std::vector<shared_ptr<JsValue>>& argv = { runtime->NewString(std::to_string(pageId)) };
3562
3563 shared_ptr<JsValue> global = runtime->GetGlobal();
3564 shared_ptr<JsValue> func = global->GetProperty(runtime, "destroyInstance");
3565 if (!func || !func->IsFunction(runtime)) {
3566 LOGE("\"destroyInstance\" not found or is not a function!");
3567 return;
3568 }
3569 func->Call(runtime, global, argv, argv.size());
3570
3571 RunGarbageCollection();
3572 }
3573
3574 // destroy application instance according to packageName
DestroyApplication(const std::string & packageName)3575 void JsiEngine::DestroyApplication(const std::string& packageName)
3576 {
3577 LOGI("JsiEngine DestroyApplication");
3578 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3579 const std::vector<shared_ptr<JsValue>>& argv = { runtime->NewString(packageName) };
3580
3581 shared_ptr<JsValue> global = runtime->GetGlobal();
3582 shared_ptr<JsValue> func = global->GetProperty(runtime, "appDestroy");
3583 if (!func || !func->IsFunction(runtime)) {
3584 LOGE("\"appDestroy\" not found or is not a function!");
3585 return;
3586 }
3587 func->Call(runtime, global, argv, argv.size());
3588 }
3589
TimerCallback(const std::string & callbackId,const std::string & delay,bool isInterval)3590 void JsiEngine::TimerCallback(const std::string& callbackId, const std::string& delay, bool isInterval)
3591 {
3592 if (isInterval) {
3593 engineInstance_->CallJs(callbackId, std::string("{}"), true, true);
3594 engineInstance_->GetFrontendDelegate()->WaitTimer(callbackId, delay, isInterval, false);
3595 } else {
3596 engineInstance_->CallJs(callbackId, std::string("{}"), false, true);
3597 engineInstance_->GetFrontendDelegate()->ClearTimer(callbackId);
3598 }
3599 }
3600
MediaQueryCallback(const std::string & callbackId,const std::string & args)3601 void JsiEngine::MediaQueryCallback(const std::string& callbackId, const std::string& args)
3602 {
3603 if (!callbackId.empty() && engineInstance_) {
3604 engineInstance_->CallJs(callbackId, args, true, false);
3605 }
3606 }
3607
RequestAnimationCallback(const std::string & callbackId,uint64_t timeStamp)3608 void JsiEngine::RequestAnimationCallback(const std::string& callbackId, uint64_t timeStamp)
3609 {
3610 if (engineInstance_) {
3611 engineInstance_->CallJs(callbackId, std::to_string(timeStamp), false, true);
3612 engineInstance_->GetFrontendDelegate()->CancelAnimationFrame(callbackId);
3613 }
3614 }
3615
JsCallback(const std::string & callbackId,const std::string & args)3616 void JsiEngine::JsCallback(const std::string& callbackId, const std::string& args)
3617 {
3618 if (engineInstance_) {
3619 engineInstance_->CallJs(callbackId, args, true, false);
3620 }
3621 }
3622
RunGarbageCollection()3623 void JsiEngine::RunGarbageCollection()
3624 {
3625 if (engineInstance_ && engineInstance_->GetJsRuntime()) {
3626 engineInstance_->GetJsRuntime()->RunGC();
3627 }
3628 }
3629
DumpHeapSnapshot(bool isPrivate)3630 void JsiEngine::DumpHeapSnapshot(bool isPrivate)
3631 {
3632 if (engineInstance_ && engineInstance_->GetJsRuntime()) {
3633 engineInstance_->GetJsRuntime()->DumpHeapSnapshot(isPrivate);
3634 }
3635 }
3636
GetStacktraceMessage()3637 std::string JsiEngine::GetStacktraceMessage()
3638 {
3639 auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine_);
3640 if (!arkNativeEngine) {
3641 LOGE("GetStacktraceMessage arkNativeEngine is nullptr");
3642 return "";
3643 }
3644 std::string stack;
3645 arkNativeEngine->SuspendVM();
3646 bool getStackSuccess = arkNativeEngine->BuildJsStackTrace(stack);
3647 arkNativeEngine->ResumeVM();
3648 if (!getStackSuccess) {
3649 LOGE("GetStacktraceMessage arkNativeEngine get stack failed");
3650 return "JS stacktrace is empty";
3651 }
3652
3653 auto runningPage = engineInstance_ ? engineInstance_->GetRunningPage() : nullptr;
3654 return JsiBaseUtils::TransSourceStack(runningPage, stack);
3655 }
3656
GetGroupJsBridge()3657 RefPtr<GroupJsBridge> JsiEngine::GetGroupJsBridge()
3658 {
3659 return AceType::MakeRefPtr<JsiGroupJsBridge>();
3660 }
3661
OnStartContinuation()3662 bool JsiEngine::OnStartContinuation()
3663 {
3664 LOGI("JsiEngine OnStartContinuation");
3665 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3666 if (!runtime) {
3667 LOGE("OnStartContinuation failed, runtime is null.");
3668 return false;
3669 }
3670
3671 return CallAppFunc("onStartContinuation");
3672 }
3673
OnCompleteContinuation(int32_t code)3674 void JsiEngine::OnCompleteContinuation(int32_t code)
3675 {
3676 LOGI("JsiEngine OnCompleteContinuation");
3677 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3678 if (!runtime) {
3679 LOGE("OnCompleteContinuation failed, runtime is null.");
3680 return;
3681 }
3682
3683 std::vector<shared_ptr<JsValue>> argv = { runtime->NewNumber(code) };
3684 CallAppFunc("onCompleteContinuation", argv);
3685 }
3686
OnRemoteTerminated()3687 void JsiEngine::OnRemoteTerminated()
3688 {
3689 LOGI("JsiEngine OnRemoteTerminated");
3690 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3691 if (!runtime) {
3692 LOGE("OnRemoteTerminated failed, runtime is null.");
3693 return;
3694 }
3695
3696 CallAppFunc("onRemoteTerminated");
3697 }
3698
OnSaveData(std::string & data)3699 void JsiEngine::OnSaveData(std::string& data)
3700 {
3701 LOGI("JsiEngine OnSaveData");
3702 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3703 if (!runtime) {
3704 LOGE("OnSaveData failed, runtime is null.");
3705 return;
3706 }
3707
3708 shared_ptr<JsValue> object = runtime->NewObject();
3709 std::vector<shared_ptr<JsValue>> argv = { object };
3710 if (CallAppFunc("onSaveData", argv)) {
3711 data = object->GetJsonString(runtime);
3712 }
3713 }
3714
OnRestoreData(const std::string & data)3715 bool JsiEngine::OnRestoreData(const std::string& data)
3716 {
3717 LOGI("JsiEngine OnRestoreData");
3718 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3719 if (!runtime) {
3720 LOGE("OnRestoreData failed, runtime is null.");
3721 return false;
3722 }
3723 shared_ptr<JsValue> result;
3724 shared_ptr<JsValue> jsonObj = runtime->ParseJson(data);
3725 if (jsonObj->IsUndefined(runtime) || jsonObj->IsException(runtime)) {
3726 LOGE("JsiEngine: Parse json for restore data failed.");
3727 return false;
3728 }
3729 std::vector<shared_ptr<JsValue>> argv = { jsonObj };
3730 return CallAppFunc("onRestoreData", argv);
3731 }
3732
CallAppFunc(const std::string & appFuncName)3733 bool JsiEngine::CallAppFunc(const std::string& appFuncName)
3734 {
3735 std::vector<shared_ptr<JsValue>> argv = {};
3736 return CallAppFunc(appFuncName, argv);
3737 }
3738
CallAppFunc(const std::string & appFuncName,std::vector<shared_ptr<JsValue>> & argv)3739 bool JsiEngine::CallAppFunc(const std::string& appFuncName, std::vector<shared_ptr<JsValue>>& argv)
3740 {
3741 LOGD("JsiEngine CallAppFunc");
3742 shared_ptr<JsRuntime> runtime = engineInstance_->GetJsRuntime();
3743 ACE_DCHECK(runtime);
3744 shared_ptr<JsValue> global = runtime->GetGlobal();
3745 shared_ptr<JsValue> appObj = global->GetProperty(runtime, "aceapp");
3746 if (!appObj->IsObject(runtime)) {
3747 LOGE("property \"aceapp\" is not a object");
3748 return false;
3749 }
3750 shared_ptr<JsValue> defaultObject = appObj->GetProperty(runtime, "$def");
3751 if (!defaultObject->IsObject(runtime)) {
3752 LOGE("property \"$def\" is not a object");
3753 return false;
3754 }
3755 shared_ptr<JsValue> func = defaultObject->GetProperty(runtime, appFuncName);
3756 if (!func || !func->IsFunction(runtime)) {
3757 LOGE("%{public}s not found or is not a function!", appFuncName.c_str());
3758 return false;
3759 }
3760 shared_ptr<JsValue> result;
3761 result = func->Call(runtime, defaultObject, argv, argv.size());
3762 return (result->ToString(runtime) == "true");
3763 }
3764
3765 } // namespace OHOS::Ace::Framework
3766