1 /*
2 * Copyright (c) 2023-2025 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 "ohos_js_environment_impl.h"
17
18 #include "console.h"
19 #include "hilog_tag_wrapper.h"
20 #include "js_utils.h"
21 #include "js_worker.h"
22 #include "ohos_loop_handler.h"
23 #include "sys_timer.h"
24 #include "worker_info.h"
25
26 namespace OHOS {
27 namespace AbilityRuntime {
28 namespace {
29 std::shared_ptr<AppExecFwk::EventHandler> g_eventHandler = nullptr;
30 }
PostTaskToHandler(const char * taskName,uv_io_cb func,void * work,int status,int priority)31 void OHOSJsEnvironmentImpl::PostTaskToHandler(const char* taskName, uv_io_cb func, void* work, int status,
32 int priority)
33 {
34 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
35 if (!func || !work) {
36 TAG_LOGE(AAFwkTag::JSRUNTIME, "Invalid parameters");
37 return;
38 }
39
40 auto task = [func, work, status]() {
41 TAG_LOGD(AAFwkTag::JSRUNTIME, "Do uv work");
42 func(work, status);
43 TAG_LOGD(AAFwkTag::JSRUNTIME, "Do uv work end");
44 };
45
46 AppExecFwk::EventQueue::Priority prio = AppExecFwk::EventQueue::Priority::IMMEDIATE;
47 switch (priority) {
48 case uv_qos_t::uv_qos_user_interactive:
49 prio = AppExecFwk::EventQueue::Priority::VIP;
50 break;
51 case uv_qos_t::uv_qos_user_initiated:
52 prio = AppExecFwk::EventQueue::Priority::IMMEDIATE;
53 break;
54 case uv_qos_t::uv_qos_utility:
55 prio = AppExecFwk::EventQueue::Priority::LOW;
56 break;
57 case uv_qos_t::uv_qos_background:
58 prio = AppExecFwk::EventQueue::Priority::IDLE;
59 break;
60 default:
61 prio = AppExecFwk::EventQueue::Priority::HIGH;
62 break;
63 }
64
65 if (g_eventHandler == nullptr) {
66 TAG_LOGE(AAFwkTag::JSRUNTIME, "Invalid parameters");
67 return;
68 }
69 if (taskName == nullptr) {
70 g_eventHandler->PostTask(task, "uv_io_cb", 0, prio);
71 } else {
72 g_eventHandler->PostTask(task, taskName, 0, prio);
73 }
74 }
OHOSJsEnvironmentImpl()75 OHOSJsEnvironmentImpl::OHOSJsEnvironmentImpl()
76 {
77 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
78 }
79
OHOSJsEnvironmentImpl(const std::shared_ptr<AppExecFwk::EventRunner> & eventRunner)80 OHOSJsEnvironmentImpl::OHOSJsEnvironmentImpl(const std::shared_ptr<AppExecFwk::EventRunner>& eventRunner)
81 {
82 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
83 if (eventRunner != nullptr) {
84 TAG_LOGD(AAFwkTag::JSRUNTIME, "Create event handler");
85 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventRunner);
86 if (eventRunner.get() == AppExecFwk::EventRunner::GetMainEventRunner().get()) {
87 g_eventHandler = std::make_shared<AppExecFwk::EventHandler>(eventRunner);
88 }
89 }
90 }
91
~OHOSJsEnvironmentImpl()92 OHOSJsEnvironmentImpl::~OHOSJsEnvironmentImpl()
93 {
94 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
95 }
96
PostTask(const std::function<void ()> & task,const std::string & name,int64_t delayTime)97 void OHOSJsEnvironmentImpl::PostTask(const std::function<void()>& task, const std::string& name, int64_t delayTime)
98 {
99 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
100 if (eventHandler_ != nullptr) {
101 eventHandler_->PostTask(task, name, delayTime);
102 }
103 }
104
PostSyncTask(const std::function<void ()> & task,const std::string & name)105 void OHOSJsEnvironmentImpl::PostSyncTask(const std::function<void()>& task, const std::string& name)
106 {
107 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
108 if (eventHandler_ != nullptr) {
109 eventHandler_->PostSyncTask(task, name);
110 }
111 }
112
RemoveTask(const std::string & name)113 void OHOSJsEnvironmentImpl::RemoveTask(const std::string& name)
114 {
115 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
116 if (eventHandler_ != nullptr) {
117 eventHandler_->RemoveTask(name);
118 }
119 }
120
InitTimerModule(NativeEngine * engine)121 void OHOSJsEnvironmentImpl::InitTimerModule(NativeEngine* engine)
122 {
123 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
124 CHECK_POINTER(engine);
125 auto ret = JsSysModule::Timer::RegisterTime(reinterpret_cast<napi_env>(engine));
126 if (!ret) {
127 TAG_LOGE(AAFwkTag::JSRUNTIME, "Register timer failed");
128 }
129 }
130
InitConsoleModule(NativeEngine * engine)131 void OHOSJsEnvironmentImpl::InitConsoleModule(NativeEngine* engine)
132 {
133 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
134 JsSysModule::Console::InitConsoleModule(reinterpret_cast<napi_env>(engine));
135 }
136
InitLoop(NativeEngine * engine,bool isStage)137 bool OHOSJsEnvironmentImpl::InitLoop(NativeEngine* engine, bool isStage)
138 {
139 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
140 CHECK_POINTER_AND_RETURN(engine, false);
141 auto uvLoop = engine->GetUVLoop();
142 auto fd = uvLoop != nullptr ? uv_backend_fd(uvLoop) : -1;
143 if (fd < 0) {
144 TAG_LOGE(AAFwkTag::JSRUNTIME, "get fd failed");
145 return false;
146 }
147 uv_run(uvLoop, UV_RUN_NOWAIT);
148
149 if (eventHandler_ != nullptr) {
150 uint32_t events = AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT | AppExecFwk::FILE_DESCRIPTOR_OUTPUT_EVENT;
151 eventHandler_->AddFileDescriptorListener(fd, events, std::make_shared<OHOSLoopHandler>(uvLoop), "uvLoopTask");
152 TAG_LOGD(AAFwkTag::JSRUNTIME, "uv_register_task_to_event, isStage: %{public}d", isStage);
153 if (isStage && (eventHandler_->GetEventRunner()).get() == AppExecFwk::EventRunner::GetMainEventRunner().get()) {
154 uv_register_task_to_event(uvLoop, PostTaskToHandler, nullptr);
155 // send signal here to trigger uv tasks generated during initialization.
156 uv_async_send(&uvLoop->wq_async);
157 }
158 }
159
160 return true;
161 }
162
DeInitLoop(NativeEngine * engine)163 void OHOSJsEnvironmentImpl::DeInitLoop(NativeEngine* engine)
164 {
165 CHECK_POINTER(engine);
166 auto uvLoop = engine->GetUVLoop();
167 auto fd = uvLoop != nullptr ? uv_backend_fd(uvLoop) : -1;
168 if (fd >= 0 && eventHandler_ != nullptr) {
169 eventHandler_->RemoveFileDescriptorListener(fd);
170 }
171 uv_unregister_task_to_event(uvLoop);
172 RemoveTask(TIMER_TASK);
173 }
174
InitWorkerModule(NativeEngine * engine,std::shared_ptr<JsEnv::WorkerInfo> workerInfo)175 void OHOSJsEnvironmentImpl::InitWorkerModule(NativeEngine* engine, std::shared_ptr<JsEnv::WorkerInfo> workerInfo)
176 {
177 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
178 CHECK_POINTER(engine);
179 CHECK_POINTER(workerInfo);
180 engine->SetInitWorkerFunc(InitWorkerFunc);
181 engine->SetOffWorkerFunc(OffWorkerFunc);
182 engine->SetReleaseWorkerSafeMemFunc(ReleaseWorkerSafeMemFunc);
183 engine->SetGetAssetFunc(AssetHelper(workerInfo));
184 engine->SetApiVersion(static_cast<int32_t>(workerInfo->apiTargetVersion.GetOriginPointer()));
185
186 engine->SetGetContainerScopeIdFunc(GetContainerId);
187 engine->SetInitContainerScopeFunc(UpdateContainerScope);
188 engine->SetFinishContainerScopeFunc(RestoreContainerScope);
189 }
190
InitSyscapModule()191 void OHOSJsEnvironmentImpl::InitSyscapModule()
192 {
193 TAG_LOGD(AAFwkTag::JSRUNTIME, "called");
194 }
195 } // namespace AbilityRuntime
196 } // namespace OHOS
197