• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "simulator.h"
17 
18 #include <condition_variable>
19 #include <fstream>
20 #include <functional>
21 #include <mutex>
22 #include <thread>
23 #include <unordered_map>
24 
25 #include "EventHandler.h"
26 #include "StageContext.h"
27 #include "ability_context.h"
28 #include "ability_stage_context.h"
29 #include "hilog_wrapper.h"
30 #include "js_ability_context.h"
31 #include "js_ability_stage_context.h"
32 #include "js_console_log.h"
33 #include "js_data_converter.h"
34 #include "js_module_searcher.h"
35 #include "js_runtime.h"
36 #include "js_runtime_utils.h"
37 #include "js_timer.h"
38 #include "js_window_stage.h"
39 #include "launch_param.h"
40 #include "native_engine/impl/ark/ark_native_engine.h"
41 #include "resource_manager.h"
42 #include "window_scene.h"
43 
44 extern const char _binary_jsMockSystemPlugin_abc_start[];
45 extern const char _binary_jsMockSystemPlugin_abc_end[];
46 
47 namespace OHOS {
48 namespace AbilityRuntime {
49 namespace {
50 constexpr int64_t DEFAULT_GC_POOL_SIZE = 0x10000000; // 256MB
51 constexpr int32_t DEFAULT_ARK_PROPERTIES = -1;
52 constexpr size_t DEFAULT_GC_THREAD_NUM = 7;
53 constexpr size_t DEFAULT_LONG_PAUSE_TIME = 40;
54 
55 constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/";
56 
57 #if defined(WINDOWS_PLATFORM)
58 constexpr char ARK_DEBUGGER_LIB_PATH[] = "libark_debugger.dll";
59 #elif defined(MAC_PLATFORM)
60 constexpr char ARK_DEBUGGER_LIB_PATH[] = "libark_debugger.dylib";
61 #else
62 #error "Unsupported platform"
63 #endif
64 
PrintVmLog(int32_t,int32_t,const char *,const char *,const char * message)65 int32_t PrintVmLog(int32_t, int32_t, const char*, const char*, const char *message)
66 {
67     HILOG_DEBUG("ArkLog: %{public}s", message);
68     return 0;
69 }
70 
71 template<typename T, size_t N>
ArraySize(T (&)[N])72 inline constexpr size_t ArraySize(T (&)[N]) noexcept
73 {
74     return N;
75 }
76 
77 struct DebuggerTask {
78     void OnPostTask(std::function<void()> &&task);
79 
80     static void HandleTask(const uv_async_t *req);
81 
82     uv_async_t onPostTaskSignal {};
83     std::function<void()> func;
84 };
85 
86 class SimulatorImpl : public Simulator {
87 public:
88     SimulatorImpl() = default;
89     ~SimulatorImpl();
90 
91     bool Initialize(const Options &options);
92 
93     int64_t StartAbility(const std::string &abilityName, TerminateCallback callback) override;
94     void TerminateAbility(int64_t abilityId) override;
95     void UpdateConfiguration(const AppExecFwk::Configuration &config) override;
96 private:
97     bool OnInit();
98     void Run();
99     NativeValue *LoadScript(const std::string &srcPath);
100     void InitResourceMgr();
101     void InitJsAbilityContext(NativeValue *instanceValue);
102     void DispatchStartLifecycle(NativeValue *instanceValue);
103     std::unique_ptr<NativeReference> CreateJsWindowStage(const std::shared_ptr<Rosen::WindowScene> &windowScene);
104     NativeValue *CreateJsWant(NativeEngine &engine);
105     bool LoadAbilityStage(uint8_t *buffer, size_t len);
106     void InitJsAbilityStageContext(NativeValue *instanceValue);
107     NativeValue *CreateJsLaunchParam(NativeEngine &engine);
108 
109     panda::ecmascript::EcmaVM *CreateJSVM();
110     Options options_;
111     std::string abilityPath_;
112     panda::ecmascript::EcmaVM *vm_ = nullptr;
113     DebuggerTask debuggerTask_;
114     std::unique_ptr<NativeEngine> nativeEngine_;
115 
116     int64_t currentId_ = 0;
117     std::unordered_map<int64_t, std::shared_ptr<NativeReference>> abilities_;
118     std::unordered_map<int64_t, std::shared_ptr<Rosen::WindowScene>> windowScenes_;
119     std::unordered_map<int64_t, std::shared_ptr<NativeReference>> jsWindowStages_;
120     std::unordered_map<int64_t, std::shared_ptr<NativeReference>> jsContexts_;
121     std::shared_ptr<Global::Resource::ResourceManager> resourceMgr_;
122     std::shared_ptr<AbilityContext> context_;
123     std::shared_ptr<NativeReference> abilityStage_;
124     std::shared_ptr<AbilityStageContext> stageContext_;
125     std::shared_ptr<NativeReference> jsStageContext_;
126 };
127 
HandleTask(const uv_async_t * req)128 void DebuggerTask::HandleTask(const uv_async_t *req)
129 {
130     auto *debuggerTask = reinterpret_cast<DebuggerTask*>(req->data);
131     if (debuggerTask == nullptr) {
132         HILOG_ERROR("HandleTask debuggerTask is null");
133         return;
134     }
135     debuggerTask->func();
136 }
137 
OnPostTask(std::function<void ()> && task)138 void DebuggerTask::OnPostTask(std::function<void()> &&task)
139 {
140     if (uv_is_active((uv_handle_t*)&onPostTaskSignal)) {
141         func = std::move(task);
142         onPostTaskSignal.data = static_cast<void*>(this);
143         uv_async_send(&onPostTaskSignal);
144     }
145 }
146 
~SimulatorImpl()147 SimulatorImpl::~SimulatorImpl()
148 {
149     if (nativeEngine_) {
150         uv_close(reinterpret_cast<uv_handle_t*>(&debuggerTask_.onPostTaskSignal), nullptr);
151         uv_loop_t *uvLoop = nativeEngine_->GetUVLoop();
152         if (uvLoop != nullptr) {
153             uv_work_t work;
154             uv_queue_work(uvLoop, &work, [](uv_work_t*) {}, [](uv_work_t *work, int32_t status) {
155                 HILOG_DEBUG("Simulator stop uv loop");
156                 uv_stop(work->loop);
157             });
158         }
159     }
160 
161     panda::JSNApi::StopDebugger(vm_);
162 
163     abilities_.clear();
164     nativeEngine_.reset();
165     panda::JSNApi::DestroyJSVM(vm_);
166     vm_ = nullptr;
167 }
168 
Initialize(const Options & options)169 bool SimulatorImpl::Initialize(const Options &options)
170 {
171     if (nativeEngine_) {
172         HILOG_DEBUG("Simulator is already initialized");
173         return true;
174     }
175 
176     options_ = options;
177     if (!OnInit()) {
178         return false;
179     }
180 
181     uv_loop_t *uvLoop = nativeEngine_->GetUVLoop();
182     if (uvLoop == nullptr) {
183         return false;
184     }
185 
186     uv_async_init(uvLoop, &debuggerTask_.onPostTaskSignal,
187         reinterpret_cast<uv_async_cb>(DebuggerTask::HandleTask));
188 
189     Run();
190     return true;
191 }
192 
CallObjectMethod(NativeEngine & engine,NativeValue * value,const char * name,NativeValue * const * argv,size_t argc)193 void CallObjectMethod(NativeEngine &engine, NativeValue *value, const char *name, NativeValue *const *argv, size_t argc)
194 {
195     NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
196     if (obj == nullptr) {
197         HILOG_ERROR("%{public}s, Failed to get Ability object", __func__);
198         return;
199     }
200 
201     NativeValue *methodOnCreate = obj->GetProperty(name);
202     if (methodOnCreate == nullptr) {
203         HILOG_ERROR("Failed to get '%{public}s' from Ability object", name);
204         return;
205     }
206     engine.CallFunction(value, methodOnCreate, argv, argc);
207 }
208 
LoadScript(const std::string & srcPath)209 NativeValue *SimulatorImpl::LoadScript(const std::string &srcPath)
210 {
211     panda::Local<panda::ObjectRef> objRef = panda::JSNApi::GetExportObject(vm_, srcPath, "default");
212     if (objRef->IsNull()) {
213         HILOG_ERROR("Get export object failed");
214         return nullptr;
215     }
216 
217     auto obj = ArkNativeEngine::ArkValueToNativeValue(static_cast<ArkNativeEngine*>(nativeEngine_.get()), objRef);
218     return nativeEngine_->CreateInstance(obj, nullptr, 0);
219 }
220 
StartAbility(const std::string & abilitySrcPath,TerminateCallback callback)221 int64_t SimulatorImpl::StartAbility(const std::string &abilitySrcPath, TerminateCallback callback)
222 {
223     std::ifstream stream(options_.modulePath, std::ios::ate | std::ios::binary);
224     if (!stream.is_open()) {
225         HILOG_ERROR("Failed to open: %{public}s", options_.modulePath.c_str());
226         return -1;
227     }
228 
229     size_t len = stream.tellg();
230     std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(len);
231     stream.seekg(0);
232     stream.read(reinterpret_cast<char*>(buffer.get()), len);
233     stream.close();
234 
235     auto buf = buffer.release();
236 
237     if (stageContext_ == nullptr) {
238         stageContext_ = std::make_shared<AbilityStageContext>();
239         stageContext_->SetOptions(options_);
240         stageContext_->SetConfiguration(options_.configuration);
241     }
242 
243     if (!LoadAbilityStage(buf, len)) {
244         HILOG_ERROR("Load ability stage failed.");
245         return -1;
246     }
247 
248     abilityPath_ = BUNDLE_INSTALL_PATH + options_.moduleName + "/" + abilitySrcPath;
249     if (!nativeEngine_->RunScriptBuffer(abilityPath_, buf, len, false)) {
250         HILOG_ERROR("Failed to run script: %{public}s", abilityPath_.c_str());
251         return -1;
252     }
253 
254     NativeValue *instanceValue = LoadScript(abilityPath_);
255     if (instanceValue == nullptr) {
256         HILOG_ERROR("Failed to create object instance");
257         return -1;
258     }
259 
260     ++currentId_;
261     InitResourceMgr();
262     InitJsAbilityContext(instanceValue);
263     DispatchStartLifecycle(instanceValue);
264     abilities_.emplace(currentId_, nativeEngine_->CreateReference(instanceValue, 1));
265 
266     return currentId_;
267 }
268 
LoadAbilityStage(uint8_t * buffer,size_t len)269 bool SimulatorImpl::LoadAbilityStage(uint8_t *buffer, size_t len)
270 {
271     if (options_.hapModuleInfo.srcEntrance.empty()) {
272         HILOG_DEBUG("module src path is empty.");
273         return true;
274     }
275 
276     if (nativeEngine_ == nullptr) {
277         HILOG_ERROR("nativeEngine_ is nullptr");
278         return false;
279     }
280     std::string srcEntrance = options_.hapModuleInfo.srcEntrance;
281     srcEntrance.erase(srcEntrance.rfind("."));
282     srcEntrance.append(".abc");
283     srcEntrance = srcEntrance.substr(srcEntrance.find('/') + 1, srcEntrance.length());
284 
285     auto moduleSrcPath = BUNDLE_INSTALL_PATH + options_.moduleName + "/" + srcEntrance;
286     if (!nativeEngine_->RunScriptBuffer(moduleSrcPath, buffer, len, false)) {
287         HILOG_ERROR("Failed to run ability stage script: %{public}s", moduleSrcPath.c_str());
288         return false;
289     }
290 
291     NativeValue *instanceValue = LoadScript(moduleSrcPath);
292     if (instanceValue == nullptr) {
293         HILOG_ERROR("Failed to create ability stage instance");
294         return false;
295     }
296 
297     InitJsAbilityStageContext(instanceValue);
298 
299     CallObjectMethod(*nativeEngine_, instanceValue, "onCreate", nullptr, 0);
300     NativeValue *wantArgv[] = {
301         CreateJsWant(*nativeEngine_)
302     };
303     CallObjectMethod(*nativeEngine_, instanceValue, "onAcceptWant", wantArgv, ArraySize(wantArgv));
304 
305     abilityStage_ = std::shared_ptr<NativeReference>(nativeEngine_->CreateReference(instanceValue, 1));
306     return true;
307 }
308 
InitJsAbilityStageContext(NativeValue * instanceValue)309 void SimulatorImpl::InitJsAbilityStageContext(NativeValue *instanceValue)
310 {
311     NativeValue *contextObj = CreateJsAbilityStageContext(*nativeEngine_, stageContext_);
312     if (contextObj == nullptr) {
313         HILOG_ERROR("contextObj is nullptr");
314         return;
315     }
316 
317     jsStageContext_ = std::shared_ptr<NativeReference>(
318         JsRuntime::LoadSystemModuleByEngine(nativeEngine_.get(), "application.AbilityStageContext", &contextObj, 1));
319     if (jsStageContext_ == nullptr) {
320         HILOG_ERROR("Failed to get LoadSystemModuleByEngine");
321         return;
322     }
323 
324     contextObj = jsStageContext_->Get();
325     if (contextObj == nullptr) {
326         HILOG_ERROR("contextObj is nullptr.");
327         return;
328     }
329 
330     NativeObject *obj = ConvertNativeValueTo<NativeObject>(instanceValue);
331     if (obj == nullptr) {
332         HILOG_ERROR("obj is nullptr");
333         return;
334     }
335     obj->SetProperty("context", contextObj);
336 }
337 
TerminateAbility(int64_t abilityId)338 void SimulatorImpl::TerminateAbility(int64_t abilityId)
339 {
340     if (abilityId == 0 && abilities_.begin() != abilities_.end()) {
341         TerminateAbility(abilities_.begin()->first);
342         return;
343     }
344 
345     auto it = abilities_.find(abilityId);
346     if (it == abilities_.end()) {
347         return;
348     }
349 
350     std::shared_ptr<NativeReference> ref = it->second;
351     abilities_.erase(it);
352 
353     auto instanceValue = ref->Get();
354     if (instanceValue == nullptr) {
355         return;
356     }
357 
358     CallObjectMethod(*nativeEngine_, instanceValue, "onBackground", nullptr, 0);
359     CallObjectMethod(*nativeEngine_, instanceValue, "onWindowStageDestroy", nullptr, 0);
360     CallObjectMethod(*nativeEngine_, instanceValue, "onDestroy", nullptr, 0);
361 
362     auto windowSceneIter = windowScenes_.find(abilityId);
363     if (windowSceneIter != windowScenes_.end()) {
364         windowScenes_.erase(windowSceneIter);
365     }
366 
367     auto windowStageIter = jsWindowStages_.find(abilityId);
368     if (windowStageIter != jsWindowStages_.end()) {
369         jsWindowStages_.erase(windowStageIter);
370     }
371 
372     auto jsContextIter = jsContexts_.find(abilityId);
373     if (jsContextIter != jsContexts_.end()) {
374         jsContexts_.erase(jsContextIter);
375     }
376 }
377 
UpdateConfiguration(const AppExecFwk::Configuration & config)378 void SimulatorImpl::UpdateConfiguration(const AppExecFwk::Configuration &config)
379 {
380     HILOG_DEBUG("called.");
381     if (abilityStage_ == nullptr) {
382         HILOG_ERROR("abilityStage_ is nullptr");
383         return;
384     }
385 
386     auto configuration = std::make_shared<AppExecFwk::Configuration>(config);
387     if (configuration == nullptr) {
388         return;
389     }
390 
391     if (stageContext_) {
392         stageContext_->SetConfiguration(configuration);
393     }
394 
395     NativeValue *configArgv[] = {
396         CreateJsConfiguration(*nativeEngine_, config)
397     };
398 
399     auto abilityStage = abilityStage_->Get();
400     if (abilityStage == nullptr) {
401         HILOG_ERROR("abilityStage is nullptr");
402         return;
403     }
404     CallObjectMethod(*nativeEngine_, abilityStage, "onConfigurationUpdated", configArgv, ArraySize(configArgv));
405     CallObjectMethod(*nativeEngine_, abilityStage, "onConfigurationUpdate", configArgv, ArraySize(configArgv));
406     JsAbilityStageContext::ConfigurationUpdated(nativeEngine_.get(), jsStageContext_, configuration);
407 
408     for (auto iter = abilities_.begin(); iter != abilities_.end(); iter++) {
409         auto ability = iter->second->Get();
410         if (ability == nullptr) {
411             HILOG_ERROR("ability is nullptr");
412             continue;
413         }
414 
415         CallObjectMethod(*nativeEngine_, ability, "onConfigurationUpdated", configArgv, ArraySize(configArgv));
416         CallObjectMethod(*nativeEngine_, ability, "onConfigurationUpdate", configArgv, ArraySize(configArgv));
417         JsAbilityContext::ConfigurationUpdated(nativeEngine_.get(), iter->second, configuration);
418     }
419 }
420 
InitResourceMgr()421 void SimulatorImpl::InitResourceMgr()
422 {
423     HILOG_DEBUG("called.");
424     resourceMgr_ = std::shared_ptr<Global::Resource::ResourceManager>(Global::Resource::CreateResourceManager());
425     if (resourceMgr_ == nullptr) {
426         HILOG_ERROR("resourceMgr is nullptr");
427         return;
428     }
429 
430     if (!resourceMgr_->AddResource(options_.resourcePath.c_str())) {
431         HILOG_ERROR("Add resource failed.");
432     }
433     HILOG_DEBUG("Add resource success.");
434 }
435 
InitJsAbilityContext(NativeValue * instanceValue)436 void SimulatorImpl::InitJsAbilityContext(NativeValue *instanceValue)
437 {
438     if (context_ == nullptr) {
439         context_ = std::make_shared<AbilityContext>();
440         context_->SetSimulator(static_cast<Simulator*>(this));
441         context_->SetOptions(options_);
442         context_->SetAbilityStageContext(stageContext_);
443         context_->SetResourceManager(resourceMgr_);
444     }
445     NativeValue *contextObj = CreateJsAbilityContext(*nativeEngine_, context_);
446     auto systemModule = std::shared_ptr<NativeReference>(
447         JsRuntime::LoadSystemModuleByEngine(nativeEngine_.get(), "application.AbilityContext", &contextObj, 1));
448     if (systemModule == nullptr) {
449         HILOG_ERROR("systemModule is nullptr.");
450         return;
451     }
452 
453     contextObj = systemModule->Get();
454     if (contextObj == nullptr) {
455         HILOG_ERROR("contextObj is nullptr.");
456         return;
457     }
458 
459     NativeObject *obj = ConvertNativeValueTo<NativeObject>(instanceValue);
460     if (obj == nullptr) {
461         HILOG_ERROR("obj is nullptr");
462         return;
463     }
464     obj->SetProperty("context", contextObj);
465     jsContexts_.emplace(currentId_, systemModule);
466 }
467 
CreateJsWant(NativeEngine & engine)468 NativeValue *SimulatorImpl::CreateJsWant(NativeEngine &engine)
469 {
470     NativeValue *objValue = engine.CreateObject();
471     NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
472 
473     object->SetProperty("deviceId", CreateJsValue(engine, ""));
474     object->SetProperty("bundleName", CreateJsValue(engine, options_.bundleName));
475     object->SetProperty("abilityName", CreateJsValue(engine, options_.abilityInfo.name));
476     object->SetProperty("moduleName", CreateJsValue(engine, options_.moduleName));
477     object->SetProperty("uri", CreateJsValue(engine, ""));
478     object->SetProperty("type", CreateJsValue(engine, ""));
479     object->SetProperty("flags", CreateJsValue(engine, 0));
480     object->SetProperty("action", CreateJsValue(engine, ""));
481     object->SetProperty("parameters", engine.CreateObject());
482     object->SetProperty("entities", engine.CreateArray(0));
483     return objValue;
484 }
485 
CreateJsLaunchParam(NativeEngine & engine)486 NativeValue *SimulatorImpl::CreateJsLaunchParam(NativeEngine &engine)
487 {
488     NativeValue *objValue = engine.CreateObject();
489     NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
490     object->SetProperty("launchReason", CreateJsValue(engine, AAFwk::LAUNCHREASON_UNKNOWN));
491     object->SetProperty("lastExitReason", CreateJsValue(engine, AAFwk::LASTEXITREASON_UNKNOWN));
492     return objValue;
493 }
494 
DispatchStartLifecycle(NativeValue * instanceValue)495 void SimulatorImpl::DispatchStartLifecycle(NativeValue *instanceValue)
496 {
497     NativeValue *wantArgv[] = {
498         CreateJsWant(*nativeEngine_),
499         CreateJsLaunchParam(*nativeEngine_)
500     };
501     CallObjectMethod(*nativeEngine_, instanceValue, "onCreate", wantArgv, ArraySize(wantArgv));
502 
503     auto windowScene = std::make_shared<Rosen::WindowScene>();
504     if (windowScene == nullptr) {
505         return;
506     }
507     sptr<Rosen::IWindowLifeCycle> listener = nullptr;
508     windowScene->Init(-1, context_, listener);
509     auto jsWindowStage = CreateJsWindowStage(windowScene);
510     if (jsWindowStage == nullptr) {
511         return;
512     }
513     NativeValue *argv[] = { jsWindowStage->Get() };
514     CallObjectMethod(*nativeEngine_, instanceValue, "onWindowStageCreate", argv, ArraySize(argv));
515 
516     CallObjectMethod(*nativeEngine_, instanceValue, "onForeground", nullptr, 0);
517 
518     windowScenes_.emplace(currentId_, windowScene);
519     jsWindowStages_.emplace(currentId_, std::shared_ptr<NativeReference>(jsWindowStage.release()));
520 }
521 
CreateJsWindowStage(const std::shared_ptr<Rosen::WindowScene> & windowScene)522 std::unique_ptr<NativeReference> SimulatorImpl::CreateJsWindowStage(
523     const std::shared_ptr<Rosen::WindowScene> &windowScene)
524 {
525     NativeValue *jsWindowStage = Rosen::CreateJsWindowStage(*nativeEngine_, windowScene);
526     if (jsWindowStage == nullptr) {
527         HILOG_ERROR("Failed to create jsWindowSatge object");
528         return nullptr;
529     }
530     return JsRuntime::LoadSystemModuleByEngine(nativeEngine_.get(), "application.WindowStage", &jsWindowStage, 1);
531 }
532 
CreateJSVM()533 panda::ecmascript::EcmaVM *SimulatorImpl::CreateJSVM()
534 {
535     panda::RuntimeOption pandaOption;
536     pandaOption.SetArkProperties(DEFAULT_ARK_PROPERTIES);
537     pandaOption.SetGcThreadNum(DEFAULT_GC_THREAD_NUM);
538     pandaOption.SetLongPauseTime(DEFAULT_LONG_PAUSE_TIME);
539     pandaOption.SetGcType(panda::RuntimeOption::GC_TYPE::GEN_GC);
540     pandaOption.SetGcPoolSize(DEFAULT_GC_POOL_SIZE);
541     pandaOption.SetLogLevel(panda::RuntimeOption::LOG_LEVEL::FOLLOW);
542     pandaOption.SetLogBufPrint(PrintVmLog);
543     pandaOption.SetEnableAsmInterpreter(true);
544     pandaOption.SetAsmOpcodeDisableRange("");
545     return panda::JSNApi::CreateJSVM(pandaOption);
546 }
547 
OnInit()548 bool SimulatorImpl::OnInit()
549 {
550     vm_ = CreateJSVM();
551     if (vm_ == nullptr) {
552         return false;
553     }
554 
555     panda::JSNApi::SetHostResolveBufferTracker(vm_,
556         [](const std::string &inputPath, uint8_t **buff, size_t *buffSize) -> bool {
557             if (inputPath.empty() || buff == nullptr || buffSize == nullptr) {
558                 HILOG_ERROR("Param invalid.");
559                 return false;
560             }
561 
562             HILOG_DEBUG("Get module buffer, input path: %{public}s.", inputPath.c_str());
563             auto data = Ide::StageContext::GetInstance().GetModuleBuffer(inputPath);
564             if (data == nullptr) {
565                 HILOG_ERROR("Get module buffer failed, input path: %{public}s.", inputPath.c_str());
566                 return false;
567             }
568 
569             *buff = data->data();
570             *buffSize = data->size();
571             return true;
572         });
573     panda::JSNApi::DebugOption debugOption = {ARK_DEBUGGER_LIB_PATH, (options_.debugPort != 0), options_.debugPort};
574     panda::JSNApi::StartDebugger(vm_, debugOption, 0,
575         std::bind(&DebuggerTask::OnPostTask, &debuggerTask_, std::placeholders::_1));
576 
577     auto nativeEngine = std::make_unique<ArkNativeEngine>(vm_, nullptr);
578 
579     NativeObject *globalObj = ConvertNativeValueTo<NativeObject>(nativeEngine->GetGlobal());
580     if (globalObj == nullptr) {
581         HILOG_ERROR("Failed to get global object");
582         return false;
583     }
584 
585     InitConsoleLogModule(*nativeEngine, *globalObj);
586     InitTimer(*nativeEngine, *globalObj);
587 
588     globalObj->SetProperty("group", nativeEngine->CreateObject());
589 
590     uintptr_t bufferStart = reinterpret_cast<uintptr_t>(_binary_jsMockSystemPlugin_abc_start);
591     uintptr_t bufferEnd = reinterpret_cast<uintptr_t>(_binary_jsMockSystemPlugin_abc_end);
592     const uint8_t *buffer = reinterpret_cast<const uint8_t*>(bufferStart);
593     size_t size = bufferEnd - bufferStart;
594 
595     panda::JSNApi::Execute(vm_, buffer, size, "_GLOBAL::func_main_0");
596 
597     NativeValue *mockRequireNapi = globalObj->GetProperty("requireNapi");
598     globalObj->SetProperty("mockRequireNapi", mockRequireNapi);
599 
600     auto* moduleManager = nativeEngine->GetModuleManager();
601     if (moduleManager != nullptr) {
602         HILOG_DEBUG("moduleManager SetPreviewSearchPath: %{public}s", options_.containerSdkPath.c_str());
603         moduleManager->SetPreviewSearchPath(options_.containerSdkPath);
604     }
605 
606     std::string fileSeparator = "/";
607     auto pos = options_.containerSdkPath.find(fileSeparator);
608     if (pos == std::string::npos) {
609         fileSeparator = "\\";
610     }
611     std::string fileName = options_.containerSdkPath + fileSeparator + "apiMock" + fileSeparator + "jsMockHmos.abc";
612     HILOG_DEBUG("file name: %{public}s", fileName.c_str());
613     if (!fileName.empty() && AbilityStageContext::Access(fileName)) {
614         panda::JSNApi::Execute(vm_, fileName, "_GLOBAL::func_main_0");
615     }
616 
617     const char *moduleName = "SimulatorImpl";
618     BindNativeFunction(*nativeEngine, *globalObj, "requireNapi", moduleName,
619         [](NativeEngine *engine, NativeCallbackInfo *info) {
620         NativeObject *globalObj = ConvertNativeValueTo<NativeObject>(engine->GetGlobal());
621         NativeValue *requireNapi = globalObj->GetProperty("requireNapiPreview");
622 
623         NativeValue *result = engine->CallFunction(engine->CreateUndefined(), requireNapi, info->argv, info->argc);
624         if (result->TypeOf() != NATIVE_UNDEFINED) {
625             return result;
626         }
627 
628         NativeValue *mockRequireNapi = globalObj->GetProperty("mockRequireNapi");
629         return engine->CallFunction(engine->CreateUndefined(), mockRequireNapi, info->argv, info->argc);
630     });
631 
632     panda::JSNApi::SetBundle(vm_, false);
633     panda::JSNApi::SetBundleName(vm_, options_.bundleName);
634     panda::JSNApi::SetModuleName(vm_, options_.moduleName);
635     panda::JSNApi::SetAssetPath(vm_, options_.modulePath);
636 
637     nativeEngine_ = std::move(nativeEngine);
638     return true;
639 }
640 
Run()641 void SimulatorImpl::Run()
642 {
643     uv_loop_t *uvLoop = nativeEngine_->GetUVLoop();
644     if (uvLoop != nullptr) {
645         uv_run(uvLoop, UV_RUN_NOWAIT);
646     }
647 
648     AppExecFwk::EventHandler::PostTask([this]() {
649         Run();
650     });
651 }
652 }
653 
Create(const Options & options)654 std::unique_ptr<Simulator> Simulator::Create(const Options &options)
655 {
656     auto simulator = std::make_unique<SimulatorImpl>();
657     if (simulator->Initialize(options)) {
658         return simulator;
659     }
660     return nullptr;
661 }
662 } // namespace AbilityRuntime
663 } // namespace OHOS
664