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