• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "js_worker.h"
17 
18 #include <cerrno>
19 #include <climits>
20 #include <cstdlib>
21 #include <fstream>
22 #include <vector>
23 #include <unistd.h>
24 
25 #include "connect_server_manager.h"
26 #ifdef SUPPORT_GRAPHICS
27 #include "core/common/container_scope.h"
28 #endif
29 #include "hilog_wrapper.h"
30 #include "js_console_log.h"
31 #include "js_runtime_utils.h"
32 #include "native_engine/impl/ark/ark_native_engine.h"
33 
34 #ifdef SUPPORT_GRAPHICS
35 using OHOS::Ace::ContainerScope;
36 #endif
37 
38 namespace OHOS {
39 namespace AbilityRuntime {
40 namespace {
41 constexpr int64_t ASSET_FILE_MAX_SIZE = 32 * 1024 * 1024;
42 const std::string BUNDLE_NAME_FLAG = "@bundle:";
43 #ifdef APP_USE_ARM
44 constexpr char ARK_DEBUGGER_LIB_PATH[] = "/system/lib/libark_debugger.z.so";
45 #else
46 constexpr char ARK_DEBUGGER_LIB_PATH[] = "/system/lib64/libark_debugger.z.so";
47 #endif
48 
49 bool g_debugMode = false;
50 
InitWorkerFunc(NativeEngine * nativeEngine)51 void InitWorkerFunc(NativeEngine* nativeEngine)
52 {
53     HILOG_INFO("InitWorkerFunc called");
54     if (nativeEngine == nullptr) {
55         HILOG_ERROR("Input nativeEngine is nullptr");
56         return;
57     }
58 
59     NativeObject* globalObj = ConvertNativeValueTo<NativeObject>(nativeEngine->GetGlobal());
60     if (globalObj == nullptr) {
61         HILOG_ERROR("Failed to get global object");
62         return;
63     }
64 
65     InitConsoleLogModule(*nativeEngine, *globalObj);
66 
67     if (g_debugMode) {
68         auto instanceId = gettid();
69         std::string instanceName = "workerThread_" + std::to_string(instanceId);
70         bool needBreakPoint = ConnectServerManager::Get().AddInstance(instanceId, instanceName);
71         auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine);
72         auto vm = const_cast<EcmaVM*>(arkNativeEngine->GetEcmaVm());
73         auto workerPostTask = [nativeEngine](std::function<void()>&& callback) {
74             nativeEngine->CallDebuggerPostTaskFunc(std::move(callback));
75         };
76         panda::JSNApi::StartDebugger(ARK_DEBUGGER_LIB_PATH, vm, needBreakPoint, instanceId, workerPostTask);
77     }
78 }
79 
OffWorkerFunc(NativeEngine * nativeEngine)80 void OffWorkerFunc(NativeEngine* nativeEngine)
81 {
82     HILOG_INFO("OffWorkerFunc called");
83     if (nativeEngine == nullptr) {
84         HILOG_ERROR("Input nativeEngine is nullptr");
85         return;
86     }
87 
88     if (g_debugMode) {
89         auto instanceId = gettid();
90         ConnectServerManager::Get().RemoveInstance(instanceId);
91         auto arkNativeEngine = static_cast<ArkNativeEngine*>(nativeEngine);
92         auto vm = const_cast<EcmaVM*>(arkNativeEngine->GetEcmaVm());
93         panda::JSNApi::StopDebugger(vm);
94     }
95 }
96 
ReadAssetData(const std::string & filePath,std::vector<uint8_t> & content,bool isDebugVersion)97 bool ReadAssetData(const std::string& filePath, std::vector<uint8_t>& content, bool isDebugVersion)
98 {
99     char path[PATH_MAX];
100     if (realpath(filePath.c_str(), path) == nullptr) {
101         HILOG_ERROR("ReadAssetData realpath(%{private}s) failed, errno = %{public}d", filePath.c_str(), errno);
102         return false;
103     }
104 
105     std::ifstream stream(path, std::ios::binary | std::ios::ate);
106     if (!stream.is_open()) {
107         HILOG_ERROR("ReadAssetData failed to open file %{private}s", filePath.c_str());
108         return false;
109     }
110 
111     auto fileLen = stream.tellg();
112     if (!isDebugVersion && fileLen > ASSET_FILE_MAX_SIZE) {
113         HILOG_ERROR("ReadAssetData failed, file is too large");
114         return false;
115     }
116 
117     content.resize(fileLen);
118 
119     stream.seekg(0);
120     stream.read(reinterpret_cast<char*>(content.data()), content.size());
121     return true;
122 }
123 
124 struct AssetHelper final {
AssetHelperOHOS::AbilityRuntime::__anonf1715a6d0111::AssetHelper125     explicit AssetHelper(const std::string& codePath, bool isDebugVersion, bool isBundle)
126         : codePath_(codePath), isDebugVersion_(isDebugVersion), isBundle_(isBundle)
127     {
128         if (!codePath_.empty() && codePath.back() != '/') {
129             codePath_.append("/");
130         }
131     }
132 
NormalizedFileNameOHOS::AbilityRuntime::__anonf1715a6d0111::AssetHelper133     std::string NormalizedFileName(const std::string& fileName) const
134     {
135         std::string normalizedFilePath;
136         size_t index = 0;
137         index = fileName.find_last_of(".");
138         // 1.1 end with file name
139         // 1.2 end with file name and file type
140         if (index == std::string::npos) {
141             HILOG_DEBUG("uri end without file type");
142             normalizedFilePath = fileName + ".abc";
143         } else {
144             HILOG_DEBUG("uri end with file type");
145             normalizedFilePath = fileName.substr(0, index) + ".abc";
146         }
147         return normalizedFilePath;
148     }
149 
operator ()OHOS::AbilityRuntime::__anonf1715a6d0111::AssetHelper150     void operator()(const std::string& uri, std::vector<uint8_t>& content, std::string &ami) const
151     {
152         if (uri.empty()) {
153             HILOG_ERROR("Uri is empty.");
154             return;
155         }
156 
157         HILOG_INFO("RegisterAssetFunc called, uri: %{private}s", uri.c_str());
158         std::string realPath;
159         std::string filePath;
160 
161         // 1. compilemode is jsbundle
162         // 2. compilemode is esmodule
163         if (isBundle_) {
164             // 1.1 start with @bundle:bundlename/modulename
165             // 1.2 start with /modulename
166             // 1.3 start with modulename
167             HILOG_DEBUG("The application is packaged using jsbundle mode.");
168             if (uri.find(BUNDLE_NAME_FLAG) == 0) {
169                 size_t index = 0;
170                 HILOG_DEBUG("uri start with @bundle:");
171                 index = uri.find_first_of("/");
172                 realPath = uri.substr(index + 1);
173             } else if (uri.find_first_of("/") == 0) {
174                 HILOG_DEBUG("uri start with /modulename");
175                 realPath = uri.substr(1);
176             } else {
177                 HILOG_DEBUG("uri start with modulename");
178                 realPath = uri;
179             }
180 
181             filePath = NormalizedFileName(realPath);
182             ami = codePath_ + filePath;
183             HILOG_DEBUG("Get asset, ami: %{private}s", ami.c_str());
184             if (!ReadAssetData(ami, content, isDebugVersion_)) {
185                 HILOG_ERROR("Get asset content failed.");
186                 return;
187             }
188         } else {
189             // 2.1 start with @bundle:bundlename/modulename
190             // 2.2 start with /modulename
191             // 2.3 start with modulename
192             HILOG_DEBUG("The application is packaged using esmodule mode.");
193             if (uri.find(BUNDLE_NAME_FLAG) == 0) {
194                 HILOG_DEBUG("uri start with @bundle:");
195                 size_t fileNamePos = uri.find_last_of("/");
196                 realPath = uri.substr(fileNamePos + 1);
197                 if (realPath.find_last_of(".") != std::string::npos) {
198                     ami = NormalizedFileName(uri);
199                 } else {
200                     ami = uri;
201                 }
202                 HILOG_DEBUG("Get asset, ami: %{private}s", ami.c_str());
203                 return;
204             } else if (uri.find_first_of("/") == 0) {
205                 HILOG_DEBUG("uri start with /modulename");
206                 realPath = uri.substr(1);
207             } else {
208                 HILOG_DEBUG("uri start with modulename");
209                 realPath = uri;
210             }
211 
212             filePath = NormalizedFileName(realPath);
213             ami = codePath_ + filePath;
214             HILOG_DEBUG("Get asset, ami: %{private}s", ami.c_str());
215         }
216     }
217 
218     std::string codePath_;
219     bool isDebugVersion_ = false;
220     bool isBundle_ = false;
221 };
222 
GetContainerId()223 int32_t GetContainerId()
224 {
225 #ifdef SUPPORT_GRAPHICS
226     int32_t scopeId = ContainerScope::CurrentId();
227     return scopeId;
228 #else
229     constexpr int32_t containerScopeDefaultId = 0;
230     return containerScopeDefaultId;
231 #endif
232 }
UpdateContainerScope(int32_t id)233 void UpdateContainerScope(int32_t id)
234 {
235 #ifdef SUPPORT_GRAPHICS
236 ContainerScope::UpdateCurrent(id);
237 #endif
238 }
RestoreContainerScope(int32_t id)239 void RestoreContainerScope(int32_t id)
240 {
241 #ifdef SUPPORT_GRAPHICS
242 ContainerScope::UpdateCurrent(-1);
243 #endif
244 }
245 }
246 
InitWorkerModule(NativeEngine & engine,const std::string & codePath,bool isDebugVersion,bool isBundle)247 void InitWorkerModule(NativeEngine& engine, const std::string& codePath, bool isDebugVersion, bool isBundle)
248 {
249     engine.SetInitWorkerFunc(InitWorkerFunc);
250     engine.SetOffWorkerFunc(OffWorkerFunc);
251     engine.SetGetAssetFunc(AssetHelper(codePath, isDebugVersion, isBundle));
252 
253     engine.SetGetContainerScopeIdFunc(GetContainerId);
254     engine.SetInitContainerScopeFunc(UpdateContainerScope);
255     engine.SetFinishContainerScopeFunc(RestoreContainerScope);
256 }
257 
StartDebuggerInWorkerModule()258 void StartDebuggerInWorkerModule()
259 {
260     g_debugMode = true;
261 }
262 } // namespace AbilityRuntime
263 } // namespace OHOS