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