1 /*
2 * Copyright (c) 2021-2024 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_context_utils.h"
17
18 #include <atomic>
19 #include <cstdint>
20
21 #include "ability_runtime_error_util.h"
22 #include "application_context.h"
23 #include "application_context_manager.h"
24 #include "hilog_tag_wrapper.h"
25 #include "ipc_skeleton.h"
26 #include "js_application_context_utils.h"
27 #include "js_data_struct_converter.h"
28 #include "js_resource_manager_utils.h"
29 #include "js_runtime_utils.h"
30 #include "tokenid_kit.h"
31 #include "js_error_utils.h"
32
33 namespace OHOS {
34 namespace AbilityRuntime {
35 namespace {
36 constexpr char BASE_CONTEXT_NAME[] = "__base_context_ptr__";
37
38 constexpr size_t ARGC_ONE = 1;
39 constexpr size_t ARGC_TWO = 2;
40 constexpr size_t INDEX_ONE = 1;
41
DetachNewApplicationContext(napi_env,void * nativeObject,void *)42 void* DetachNewApplicationContext(napi_env, void* nativeObject, void*)
43 {
44 auto* origContext = static_cast<std::weak_ptr<ApplicationContext> *>(nativeObject);
45 if (origContext == nullptr) {
46 TAG_LOGE(AAFwkTag::APPKIT, "origContext is null");
47 return nullptr;
48 }
49 TAG_LOGD(AAFwkTag::APPKIT, "New detached application context");
50 auto* detachNewContext = new(std::nothrow) std::weak_ptr<ApplicationContext>(*origContext);
51 return detachNewContext;
52 }
53
DetachNewBaseContext(napi_env,void * nativeObject,void *)54 void* DetachNewBaseContext(napi_env, void* nativeObject, void*)
55 {
56 auto* origContext = static_cast<std::weak_ptr<Context> *>(nativeObject);
57 if (origContext == nullptr) {
58 TAG_LOGE(AAFwkTag::APPKIT, "origContext is null");
59 return nullptr;
60 }
61 TAG_LOGD(AAFwkTag::APPKIT, "New detached base context");
62 auto* detachNewContext = new(std::nothrow) std::weak_ptr<Context>(*origContext);
63 return detachNewContext;
64 }
65
DetachFinalizeApplicationContext(void * detachedObject,void *)66 void DetachFinalizeApplicationContext(void* detachedObject, void*)
67 {
68 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer detached application context");
69 delete static_cast<std::weak_ptr<ApplicationContext> *>(detachedObject);
70 }
71
DetachFinalizeBaseContext(void * detachedObject,void *)72 void DetachFinalizeBaseContext(void* detachedObject, void*)
73 {
74 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer detached base context");
75 delete static_cast<std::weak_ptr<Context> *>(detachedObject);
76 }
77
78 class JsBaseContext {
79 public:
JsBaseContext(std::weak_ptr<Context> && context)80 explicit JsBaseContext(std::weak_ptr<Context>&& context) : context_(std::move(context)) {}
81 virtual ~JsBaseContext() = default;
82
83 static void Finalizer(napi_env env, void* data, void* hint);
84 static napi_value CreateBundleContext(napi_env env, napi_callback_info info);
85 static napi_value GetApplicationContext(napi_env env, napi_callback_info info);
86 static napi_value SwitchArea(napi_env env, napi_callback_info info);
87 static napi_value GetArea(napi_env env, napi_callback_info info);
88 static napi_value CreateModuleContext(napi_env env, napi_callback_info info);
89 static napi_value CreateSystemHspModuleResourceManager(napi_env env, napi_callback_info info);
90 static napi_value CreateModuleResourceManager(napi_env env, napi_callback_info info);
91 static napi_value CreateAreaModeContext(napi_env env, napi_callback_info info);
92 static napi_value CreateDisplayContext(napi_env env, napi_callback_info info);
93
94 napi_value OnGetCacheDir(napi_env env, NapiCallbackInfo& info);
95 napi_value OnGetTempDir(napi_env env, NapiCallbackInfo& info);
96 napi_value OnGetResourceDir(napi_env env, NapiCallbackInfo& info);
97 napi_value OnGetFilesDir(napi_env env, NapiCallbackInfo& info);
98 napi_value OnGetDistributedFilesDir(napi_env env, NapiCallbackInfo& info);
99 napi_value OnGetDatabaseDir(napi_env env, NapiCallbackInfo& info);
100 napi_value OnGetPreferencesDir(napi_env env, NapiCallbackInfo& info);
101 napi_value OnGetGroupDir(napi_env env, NapiCallbackInfo& info);
102 napi_value OnGetBundleCodeDir(napi_env env, NapiCallbackInfo& info);
103 napi_value OnGetCloudFileDir(napi_env env, NapiCallbackInfo& info);
104 napi_value OnGetProcessName(napi_env env, NapiCallbackInfo &info);
105
106 static napi_value GetCacheDir(napi_env env, napi_callback_info info);
107 static napi_value GetTempDir(napi_env env, napi_callback_info info);
108 static napi_value GetResourceDir(napi_env env, napi_callback_info info);
109 static napi_value GetFilesDir(napi_env env, napi_callback_info info);
110 static napi_value GetDistributedFilesDir(napi_env env, napi_callback_info info);
111 static napi_value GetDatabaseDir(napi_env env, napi_callback_info info);
112 static napi_value GetPreferencesDir(napi_env env, napi_callback_info info);
113 static napi_value GetGroupDir(napi_env env, napi_callback_info info);
114 static napi_value GetBundleCodeDir(napi_env env, napi_callback_info info);
115 static napi_value GetCloudFileDir(napi_env env, napi_callback_info info);
116 static napi_value GetProcessName(napi_env env, napi_callback_info info);
117
118 protected:
119 std::weak_ptr<Context> context_;
120
121 private:
122 napi_value OnCreateBundleContext(napi_env env, NapiCallbackInfo& info);
123 napi_value CreateJsBundleContext(napi_env env, const std::shared_ptr<Context>& bundleContext);
124 napi_value OnGetApplicationContext(napi_env env, NapiCallbackInfo& info);
125 napi_value CreateJSApplicationContext(napi_env env, const std::shared_ptr<ApplicationContext> applicationContext);
126 napi_value OnSwitchArea(napi_env env, NapiCallbackInfo& info);
127 napi_value OnGetArea(napi_env env, NapiCallbackInfo& info);
128 napi_value OnCreateModuleContext(napi_env env, NapiCallbackInfo& info);
129 napi_value CreateJsModuleContext(napi_env env, const std::shared_ptr<Context>& moduleContext);
130 napi_value OnCreateSystemHspModuleResourceManager(napi_env env, NapiCallbackInfo& info);
131 napi_value OnCreateModuleResourceManager(napi_env env, NapiCallbackInfo& info);
132 napi_value OnCreateAreaModeContext(napi_env env, NapiCallbackInfo &info);
133 napi_value OnCreateDisplayContext(napi_env env, NapiCallbackInfo &info);
134 napi_value CreateJsContext(napi_env env, const std::shared_ptr<Context> &context);
135 bool CheckCallerIsSystemApp();
136 };
137
Finalizer(napi_env env,void * data,void * hint)138 void JsBaseContext::Finalizer(napi_env env, void* data, void* hint)
139 {
140 TAG_LOGD(AAFwkTag::APPKIT, "called");
141 std::unique_ptr<JsBaseContext>(static_cast<JsBaseContext*>(data));
142 }
143
CreateBundleContext(napi_env env,napi_callback_info info)144 napi_value JsBaseContext::CreateBundleContext(napi_env env, napi_callback_info info)
145 {
146 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateBundleContext, BASE_CONTEXT_NAME);
147 }
148
GetApplicationContext(napi_env env,napi_callback_info info)149 napi_value JsBaseContext::GetApplicationContext(napi_env env, napi_callback_info info)
150 {
151 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetApplicationContext, BASE_CONTEXT_NAME);
152 }
153
SwitchArea(napi_env env,napi_callback_info info)154 napi_value JsBaseContext::SwitchArea(napi_env env, napi_callback_info info)
155 {
156 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnSwitchArea, BASE_CONTEXT_NAME);
157 }
158
OnSwitchArea(napi_env env,NapiCallbackInfo & info)159 napi_value JsBaseContext::OnSwitchArea(napi_env env, NapiCallbackInfo& info)
160 {
161 if (info.argc == 0) {
162 TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
163 return CreateJsUndefined(env);
164 }
165
166 auto context = context_.lock();
167 if (!context) {
168 TAG_LOGW(AAFwkTag::APPKIT, "null context");
169 return CreateJsUndefined(env);
170 }
171
172 int mode = 0;
173 if (!ConvertFromJsValue(env, info.argv[0], mode)) {
174 TAG_LOGE(AAFwkTag::APPKIT, "Parse mode failed");
175 return CreateJsUndefined(env);
176 }
177
178 context->SwitchArea(mode);
179
180 napi_value object = info.thisVar;
181 if (!CheckTypeForNapiValue(env, object, napi_object)) {
182 TAG_LOGE(AAFwkTag::APPKIT, "Check type failed");
183 return CreateJsUndefined(env);
184 }
185 BindNativeProperty(env, object, "cacheDir", GetCacheDir);
186 BindNativeProperty(env, object, "tempDir", GetTempDir);
187 BindNativeProperty(env, object, "resourceDir", GetResourceDir);
188 BindNativeProperty(env, object, "filesDir", GetFilesDir);
189 BindNativeProperty(env, object, "distributedFilesDir", GetDistributedFilesDir);
190 BindNativeProperty(env, object, "databaseDir", GetDatabaseDir);
191 BindNativeProperty(env, object, "preferencesDir", GetPreferencesDir);
192 BindNativeProperty(env, object, "bundleCodeDir", GetBundleCodeDir);
193 BindNativeProperty(env, object, "cloudFileDir", GetCloudFileDir);
194 return CreateJsUndefined(env);
195 }
196
CreateModuleContext(napi_env env,napi_callback_info info)197 napi_value JsBaseContext::CreateModuleContext(napi_env env, napi_callback_info info)
198 {
199 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateModuleContext, BASE_CONTEXT_NAME);
200 }
201
OnCreateModuleContext(napi_env env,NapiCallbackInfo & info)202 napi_value JsBaseContext::OnCreateModuleContext(napi_env env, NapiCallbackInfo& info)
203 {
204 auto context = context_.lock();
205 if (!context) {
206 TAG_LOGW(AAFwkTag::APPKIT, "null context");
207 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
208 return CreateJsUndefined(env);
209 }
210
211 std::shared_ptr<Context> moduleContext = nullptr;
212 std::string moduleName;
213
214 if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
215 TAG_LOGD(AAFwkTag::APPKIT, "Parse inner module name");
216 if (!ConvertFromJsValue(env, info.argv[0], moduleName)) {
217 TAG_LOGE(AAFwkTag::APPKIT, "Parse moduleName failed");
218 ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
219 return CreateJsUndefined(env);
220 }
221 moduleContext = context->CreateModuleContext(moduleName);
222 } else {
223 std::string bundleName;
224 if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
225 TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
226 ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
227 return CreateJsUndefined(env);
228 }
229 if (!CheckCallerIsSystemApp()) {
230 TAG_LOGE(AAFwkTag::APPKIT, "not system-app");
231 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
232 return CreateJsUndefined(env);
233 }
234 TAG_LOGD(AAFwkTag::APPKIT, "Parse outer module name");
235 moduleContext = context->CreateModuleContext(bundleName, moduleName);
236 }
237
238 if (!moduleContext) {
239 TAG_LOGE(AAFwkTag::APPKIT, "null moduleContext");
240 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
241 return CreateJsUndefined(env);
242 }
243 return CreateJsModuleContext(env, moduleContext);
244 }
245
CreateJsModuleContext(napi_env env,const std::shared_ptr<Context> & moduleContext)246 napi_value JsBaseContext::CreateJsModuleContext(napi_env env, const std::shared_ptr<Context>& moduleContext)
247 {
248 napi_value value = CreateJsBaseContext(env, moduleContext, true);
249 auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
250 if (systemModule == nullptr) {
251 TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
252 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
253 return CreateJsUndefined(env);
254 }
255 napi_value object = systemModule->GetNapiValue();
256 if (!CheckTypeForNapiValue(env, object, napi_object)) {
257 TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
258 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
259 return CreateJsUndefined(env);
260 }
261 auto workContext = new (std::nothrow) std::weak_ptr<Context>(moduleContext);
262 napi_coerce_to_native_binding_object(env, object, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
263 auto res = napi_wrap(env, object, workContext,
264 [](napi_env, void *data, void *) {
265 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr module context is called");
266 delete static_cast<std::weak_ptr<Context> *>(data);
267 },
268 nullptr, nullptr);
269 if (res != napi_ok && workContext != nullptr) {
270 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
271 delete workContext;
272 return CreateJsUndefined(env);
273 }
274 return object;
275 }
276
CreateSystemHspModuleResourceManager(napi_env env,napi_callback_info info)277 napi_value JsBaseContext::CreateSystemHspModuleResourceManager(napi_env env, napi_callback_info info)
278 {
279 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext,
280 OnCreateSystemHspModuleResourceManager, BASE_CONTEXT_NAME);
281 }
282
OnCreateSystemHspModuleResourceManager(napi_env env,NapiCallbackInfo & info)283 napi_value JsBaseContext::OnCreateSystemHspModuleResourceManager(napi_env env, NapiCallbackInfo& info)
284 {
285 auto context = context_.lock();
286 if (!context) {
287 TAG_LOGW(AAFwkTag::APPKIT, "null context");
288 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
289 return CreateJsUndefined(env);
290 }
291
292 std::string bundleName = "";
293 if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
294 TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
295 ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
296 return CreateJsUndefined(env);
297 }
298 std::string moduleName = "";
299 if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
300 TAG_LOGE(AAFwkTag::APPKIT, "Parse moduleName failed");
301 ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
302 return CreateJsUndefined(env);
303 }
304
305 std::shared_ptr<Global::Resource::ResourceManager> resourceManager = nullptr;
306 int32_t retCode = context->CreateSystemHspModuleResourceManager(bundleName, moduleName, resourceManager);
307 if (resourceManager == nullptr && retCode == ERR_ABILITY_RUNTIME_EXTERNAL_NOT_SYSTEM_HSP) {
308 TAG_LOGE(AAFwkTag::APPKIT, "null resourceManager");
309 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_NOT_SYSTEM_HSP);
310 return CreateJsUndefined(env);
311 }
312 if (resourceManager == nullptr) {
313 TAG_LOGE(AAFwkTag::APPKIT, "null resourceManager");
314 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
315 return CreateJsUndefined(env);
316 }
317
318 return CreateJsResourceManager(env, resourceManager, nullptr);
319 }
320
CreateModuleResourceManager(napi_env env,napi_callback_info info)321 napi_value JsBaseContext::CreateModuleResourceManager(napi_env env, napi_callback_info info)
322 {
323 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateModuleResourceManager, BASE_CONTEXT_NAME);
324 }
325
OnCreateModuleResourceManager(napi_env env,NapiCallbackInfo & info)326 napi_value JsBaseContext::OnCreateModuleResourceManager(napi_env env, NapiCallbackInfo& info)
327 {
328 auto context = context_.lock();
329 if (!context) {
330 TAG_LOGW(AAFwkTag::APPKIT, "null context");
331 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
332 return CreateJsUndefined(env);
333 }
334
335 std::string bundleName;
336 if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
337 TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
338 ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
339 return CreateJsUndefined(env);
340 }
341 std::string moduleName;
342 if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
343 TAG_LOGE(AAFwkTag::APPKIT, "Parse moduleName failed");
344 ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
345 return CreateJsUndefined(env);
346 }
347 if (!CheckCallerIsSystemApp()) {
348 TAG_LOGE(AAFwkTag::APPKIT, "not system-app");
349 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
350 return CreateJsUndefined(env);
351 }
352 auto resourceManager = context->CreateModuleResourceManager(bundleName, moduleName);
353 if (resourceManager == nullptr) {
354 TAG_LOGE(AAFwkTag::APPKIT, "null resourceManager");
355 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
356 return CreateJsUndefined(env);
357 }
358 auto jsResourceManager = CreateJsResourceManager(env, resourceManager, nullptr);
359 return jsResourceManager;
360 }
361
GetArea(napi_env env,napi_callback_info info)362 napi_value JsBaseContext::GetArea(napi_env env, napi_callback_info info)
363 {
364 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetArea, BASE_CONTEXT_NAME);
365 }
366
OnGetArea(napi_env env,NapiCallbackInfo & info)367 napi_value JsBaseContext::OnGetArea(napi_env env, NapiCallbackInfo& info)
368 {
369 auto context = context_.lock();
370 if (!context) {
371 TAG_LOGW(AAFwkTag::APPKIT, "null context");
372 return CreateJsUndefined(env);
373 }
374 int area = context->GetArea();
375 return CreateJsValue(env, area);
376 }
377
GetCacheDir(napi_env env,napi_callback_info info)378 napi_value JsBaseContext::GetCacheDir(napi_env env, napi_callback_info info)
379 {
380 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetCacheDir, BASE_CONTEXT_NAME);
381 }
382
OnGetCacheDir(napi_env env,NapiCallbackInfo & info)383 napi_value JsBaseContext::OnGetCacheDir(napi_env env, NapiCallbackInfo& info)
384 {
385 auto context = context_.lock();
386 if (!context) {
387 TAG_LOGW(AAFwkTag::APPKIT, "null context");
388 return CreateJsUndefined(env);
389 }
390 std::string path = context->GetCacheDir();
391 return CreateJsValue(env, path);
392 }
393
GetTempDir(napi_env env,napi_callback_info info)394 napi_value JsBaseContext::GetTempDir(napi_env env, napi_callback_info info)
395 {
396 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetTempDir, BASE_CONTEXT_NAME);
397 }
398
OnGetTempDir(napi_env env,NapiCallbackInfo & info)399 napi_value JsBaseContext::OnGetTempDir(napi_env env, NapiCallbackInfo& info)
400 {
401 auto context = context_.lock();
402 if (!context) {
403 TAG_LOGW(AAFwkTag::APPKIT, "null context");
404 return CreateJsUndefined(env);
405 }
406 std::string path = context->GetTempDir();
407 return CreateJsValue(env, path);
408 }
409
GetResourceDir(napi_env env,napi_callback_info info)410 napi_value JsBaseContext::GetResourceDir(napi_env env, napi_callback_info info)
411 {
412 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetResourceDir, BASE_CONTEXT_NAME);
413 }
414
OnGetResourceDir(napi_env env,NapiCallbackInfo & info)415 napi_value JsBaseContext::OnGetResourceDir(napi_env env, NapiCallbackInfo& info)
416 {
417 auto context = context_.lock();
418 if (!context) {
419 TAG_LOGW(AAFwkTag::APPKIT, "null context");
420 return CreateJsUndefined(env);
421 }
422 std::string path = context->GetResourceDir();
423 return CreateJsValue(env, path);
424 }
425
GetFilesDir(napi_env env,napi_callback_info info)426 napi_value JsBaseContext::GetFilesDir(napi_env env, napi_callback_info info)
427 {
428 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetFilesDir, BASE_CONTEXT_NAME);
429 }
430
OnGetFilesDir(napi_env env,NapiCallbackInfo & info)431 napi_value JsBaseContext::OnGetFilesDir(napi_env env, NapiCallbackInfo& info)
432 {
433 auto context = context_.lock();
434 if (!context) {
435 TAG_LOGW(AAFwkTag::APPKIT, "null context");
436 return CreateJsUndefined(env);
437 }
438 std::string path = context->GetFilesDir();
439 return CreateJsValue(env, path);
440 }
441
GetDistributedFilesDir(napi_env env,napi_callback_info info)442 napi_value JsBaseContext::GetDistributedFilesDir(napi_env env, napi_callback_info info)
443 {
444 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetDistributedFilesDir, BASE_CONTEXT_NAME);
445 }
446
OnGetDistributedFilesDir(napi_env env,NapiCallbackInfo & info)447 napi_value JsBaseContext::OnGetDistributedFilesDir(napi_env env, NapiCallbackInfo& info)
448 {
449 auto context = context_.lock();
450 if (!context) {
451 TAG_LOGW(AAFwkTag::APPKIT, "null context");
452 return CreateJsUndefined(env);
453 }
454 std::string path = context->GetDistributedFilesDir();
455 return CreateJsValue(env, path);
456 }
457
GetDatabaseDir(napi_env env,napi_callback_info info)458 napi_value JsBaseContext::GetDatabaseDir(napi_env env, napi_callback_info info)
459 {
460 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetDatabaseDir, BASE_CONTEXT_NAME);
461 }
462
OnGetDatabaseDir(napi_env env,NapiCallbackInfo & info)463 napi_value JsBaseContext::OnGetDatabaseDir(napi_env env, NapiCallbackInfo& info)
464 {
465 auto context = context_.lock();
466 if (!context) {
467 TAG_LOGW(AAFwkTag::APPKIT, "null context");
468 return CreateJsUndefined(env);
469 }
470 std::string path = context->GetDatabaseDir();
471 return CreateJsValue(env, path);
472 }
473
GetPreferencesDir(napi_env env,napi_callback_info info)474 napi_value JsBaseContext::GetPreferencesDir(napi_env env, napi_callback_info info)
475 {
476 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetPreferencesDir, BASE_CONTEXT_NAME);
477 }
478
OnGetPreferencesDir(napi_env env,NapiCallbackInfo & info)479 napi_value JsBaseContext::OnGetPreferencesDir(napi_env env, NapiCallbackInfo& info)
480 {
481 auto context = context_.lock();
482 if (!context) {
483 TAG_LOGW(AAFwkTag::APPKIT, "null context");
484 return CreateJsUndefined(env);
485 }
486 std::string path = context->GetPreferencesDir();
487 return CreateJsValue(env, path);
488 }
489
GetGroupDir(napi_env env,napi_callback_info info)490 napi_value JsBaseContext::GetGroupDir(napi_env env, napi_callback_info info)
491 {
492 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetGroupDir, BASE_CONTEXT_NAME);
493 }
494
OnGetGroupDir(napi_env env,NapiCallbackInfo & info)495 napi_value JsBaseContext::OnGetGroupDir(napi_env env, NapiCallbackInfo& info)
496 {
497 if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
498 TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
499 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
500 return CreateJsUndefined(env);
501 }
502
503 std::string groupId;
504 if (!ConvertFromJsValue(env, info.argv[0], groupId)) {
505 TAG_LOGE(AAFwkTag::APPKIT, "Parse groupId failed");
506 ThrowInvalidParamError(env, "Parse param groupId failed, groupId must be string.");
507 return CreateJsUndefined(env);
508 }
509 auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
510 auto path = std::make_shared<std::string>();
511 NapiAsyncTask::ExecuteCallback execute = [context = context_, groupId, path, innerErrCode]() {
512 auto completeContext = context.lock();
513 if (!completeContext) {
514 *innerErrCode = ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST;
515 return;
516 }
517 *path = completeContext->GetGroupDir(groupId);
518 };
519 auto complete = [innerErrCode, path]
520 (napi_env env, NapiAsyncTask& task, int32_t status) {
521 if (*innerErrCode == ERR_OK) {
522 task.ResolveWithNoError(env, CreateJsValue(env, *path));
523 } else {
524 task.Reject(env, CreateJsError(env, *innerErrCode, "completeContext if already released."));
525 }
526 };
527
528 napi_value lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
529 napi_value result = nullptr;
530 NapiAsyncTask::ScheduleHighQos("JsBaseContext::OnGetGroupDir",
531 env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
532 return result;
533 }
534
GetBundleCodeDir(napi_env env,napi_callback_info info)535 napi_value JsBaseContext::GetBundleCodeDir(napi_env env, napi_callback_info info)
536 {
537 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetBundleCodeDir, BASE_CONTEXT_NAME);
538 }
539
OnGetBundleCodeDir(napi_env env,NapiCallbackInfo & info)540 napi_value JsBaseContext::OnGetBundleCodeDir(napi_env env, NapiCallbackInfo& info)
541 {
542 auto context = context_.lock();
543 if (!context) {
544 TAG_LOGW(AAFwkTag::APPKIT, "null context");
545 return CreateJsUndefined(env);
546 }
547 std::string path = context->GetBundleCodeDir();
548 return CreateJsValue(env, path);
549 }
550
GetCloudFileDir(napi_env env,napi_callback_info info)551 napi_value JsBaseContext::GetCloudFileDir(napi_env env, napi_callback_info info)
552 {
553 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetCloudFileDir, BASE_CONTEXT_NAME);
554 }
555
OnGetCloudFileDir(napi_env env,NapiCallbackInfo & info)556 napi_value JsBaseContext::OnGetCloudFileDir(napi_env env, NapiCallbackInfo& info)
557 {
558 auto context = context_.lock();
559 if (!context) {
560 TAG_LOGW(AAFwkTag::APPKIT, "null context");
561 return CreateJsUndefined(env);
562 }
563 std::string path = context->GetCloudFileDir();
564 return CreateJsValue(env, path);
565 }
566
GetProcessName(napi_env env,napi_callback_info info)567 napi_value JsBaseContext::GetProcessName(napi_env env, napi_callback_info info)
568 {
569 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetProcessName, BASE_CONTEXT_NAME);
570 }
571
OnGetProcessName(napi_env env,NapiCallbackInfo & info)572 napi_value JsBaseContext::OnGetProcessName(napi_env env, NapiCallbackInfo &info)
573 {
574 auto context = context_.lock();
575 if (context == nullptr) {
576 TAG_LOGE(AAFwkTag::APPKIT, "context is already released");
577 return CreateJsUndefined(env);
578 }
579 std::string name = context->GetProcessName();
580 return CreateJsValue(env, name);
581 }
582
OnCreateBundleContext(napi_env env,NapiCallbackInfo & info)583 napi_value JsBaseContext::OnCreateBundleContext(napi_env env, NapiCallbackInfo& info)
584 {
585 if (!CheckCallerIsSystemApp()) {
586 TAG_LOGE(AAFwkTag::APPKIT, "not system-app");
587 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
588 return CreateJsUndefined(env);
589 }
590
591 if (info.argc == 0) {
592 TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
593 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
594 return CreateJsUndefined(env);
595 }
596
597 auto context = context_.lock();
598 if (!context) {
599 TAG_LOGW(AAFwkTag::APPKIT, "null context");
600 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
601 return CreateJsUndefined(env);
602 }
603
604 std::string bundleName;
605 if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
606 TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
607 ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
608 return CreateJsUndefined(env);
609 }
610
611 auto bundleContext = context->CreateBundleContext(bundleName);
612 if (!bundleContext) {
613 TAG_LOGE(AAFwkTag::APPKIT, "null bundleContext");
614 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
615 return CreateJsUndefined(env);
616 }
617 return CreateJsBundleContext(env, bundleContext);
618 }
619
CreateJsBundleContext(napi_env env,const std::shared_ptr<Context> & bundleContext)620 napi_value JsBaseContext::CreateJsBundleContext(napi_env env, const std::shared_ptr<Context>& bundleContext)
621 {
622 napi_value value = CreateJsBaseContext(env, bundleContext, true);
623 auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
624 if (systemModule == nullptr) {
625 TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
626 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
627 return CreateJsUndefined(env);
628 }
629 napi_value object = systemModule->GetNapiValue();
630 if (!CheckTypeForNapiValue(env, object, napi_object)) {
631 TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
632 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
633 return CreateJsUndefined(env);
634 }
635 auto workContext = new (std::nothrow) std::weak_ptr<Context>(bundleContext);
636 napi_coerce_to_native_binding_object(env, object, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
637 auto res = napi_wrap(env, object, workContext,
638 [](napi_env, void *data, void *) {
639 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr bundle context is called");
640 delete static_cast<std::weak_ptr<Context> *>(data);
641 },
642 nullptr, nullptr);
643 if (res != napi_ok && workContext != nullptr) {
644 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
645 delete workContext;
646 return CreateJsUndefined(env);
647 }
648 return object;
649 }
650
OnGetApplicationContext(napi_env env,NapiCallbackInfo & info)651 napi_value JsBaseContext::OnGetApplicationContext(napi_env env, NapiCallbackInfo& info)
652 {
653 auto context = context_.lock();
654 if (!context) {
655 TAG_LOGW(AAFwkTag::APPKIT, "null context");
656 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
657 return CreateJsUndefined(env);
658 }
659
660 auto applicationContext = Context::GetApplicationContext();
661 if (applicationContext == nullptr) {
662 TAG_LOGW(AAFwkTag::APPKIT, "null applicationContext");
663 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
664 return CreateJsUndefined(env);
665 }
666
667 if (!applicationContext->GetApplicationInfoUpdateFlag()) {
668 std::shared_ptr<NativeReference> applicationContextObj =
669 ApplicationContextManager::GetApplicationContextManager().GetGlobalObject(env);
670 if (applicationContextObj != nullptr) {
671 napi_value objValue = applicationContextObj->GetNapiValue();
672 return objValue;
673 }
674 }
675 return CreateJSApplicationContext(env, applicationContext);
676 }
677
CreateAreaModeContext(napi_env env,napi_callback_info info)678 napi_value JsBaseContext::CreateAreaModeContext(napi_env env, napi_callback_info info)
679 {
680 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateAreaModeContext, BASE_CONTEXT_NAME);
681 }
682
OnCreateAreaModeContext(napi_env env,NapiCallbackInfo & info)683 napi_value JsBaseContext::OnCreateAreaModeContext(napi_env env, NapiCallbackInfo &info)
684 {
685 if (info.argc == 0) {
686 TAG_LOGE(AAFwkTag::APPKIT, "not enough params");
687 ThrowTooFewParametersError(env);
688 return CreateJsUndefined(env);
689 }
690
691 auto context = context_.lock();
692 if (context == nullptr) {
693 TAG_LOGE(AAFwkTag::APPKIT, "context is already released");
694 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
695 return CreateJsUndefined(env);
696 }
697
698 int areaMode = 0;
699 if (!ConvertFromJsValue(env, info.argv[0], areaMode)) {
700 TAG_LOGE(AAFwkTag::APPKIT, "parse areaMode failed");
701 ThrowInvalidParamError(env, "parse param areaMode failed, areaMode must be number.");
702 return CreateJsUndefined(env);
703 }
704 auto areaContext = context->CreateAreaModeContext(areaMode);
705 if (areaContext == nullptr) {
706 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
707 TAG_LOGE(AAFwkTag::APPKIT, "failed to create areaContext");
708 return CreateJsUndefined(env);
709 }
710
711 return CreateJsContext(env, areaContext);
712 }
713
CreateDisplayContext(napi_env env,napi_callback_info info)714 napi_value JsBaseContext::CreateDisplayContext(napi_env env, napi_callback_info info)
715 {
716 GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateDisplayContext, BASE_CONTEXT_NAME);
717 }
718
OnCreateDisplayContext(napi_env env,NapiCallbackInfo & info)719 napi_value JsBaseContext::OnCreateDisplayContext(napi_env env, NapiCallbackInfo &info)
720 {
721 #ifdef SUPPORT_GRAPHICS
722 if (info.argc == 0) {
723 TAG_LOGE(AAFwkTag::APPKIT, "not enough params");
724 ThrowTooFewParametersError(env);
725 return CreateJsUndefined(env);
726 }
727
728 auto context = context_.lock();
729 if (context == nullptr) {
730 TAG_LOGE(AAFwkTag::APPKIT, "context is already released");
731 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
732 return CreateJsUndefined(env);
733 }
734
735 int64_t displayId = -1;
736 if (!ConvertFromJsValue(env, info.argv[0], displayId)) {
737 TAG_LOGE(AAFwkTag::APPKIT, "parse displayId failed");
738 ThrowInvalidParamError(env, "parse param displayId failed, displayId must be number.");
739 return CreateJsUndefined(env);
740 }
741 if (displayId < 0) {
742 TAG_LOGE(AAFwkTag::APPKIT, "displayId is invalid, less than 0");
743 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
744 return CreateJsUndefined(env);
745 }
746 uint64_t validDisplayId = static_cast<uint64_t>(displayId);
747
748 auto displayContext = context->CreateDisplayContext(validDisplayId);
749 if (displayContext == nullptr) {
750 TAG_LOGE(AAFwkTag::APPKIT, "failed to create displayContext");
751 return CreateJsUndefined(env);
752 }
753 return CreateJsContext(env, displayContext);
754 #else
755 return CreateJsUndefined(env);
756 #endif
757 }
758
CreateJsContext(napi_env env,const std::shared_ptr<Context> & context)759 napi_value JsBaseContext::CreateJsContext(napi_env env, const std::shared_ptr<Context> &context)
760 {
761 napi_value value = CreateJsBaseContext(env, context, true);
762 auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
763 if (systemModule == nullptr) {
764 TAG_LOGE(AAFwkTag::APPKIT, "invalid systemModule");
765 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
766 return CreateJsUndefined(env);
767 }
768 napi_value object = systemModule->GetNapiValue();
769 if (!CheckTypeForNapiValue(env, object, napi_object)) {
770 TAG_LOGE(AAFwkTag::APPKIT, "failed to get object");
771 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
772 return CreateJsUndefined(env);
773 }
774 auto workContext = new (std::nothrow) std::weak_ptr<Context>(context);
775 auto status = napi_coerce_to_native_binding_object(env, object, DetachCallbackFunc, AttachBaseContext,
776 workContext, nullptr);
777 if (status != napi_ok) {
778 TAG_LOGE(AAFwkTag::APPKIT, "coerce context failed: %{public}d", status);
779 delete workContext;
780 return CreateJsUndefined(env);
781 }
782 auto res = napi_wrap(env, object, workContext,
783 [](napi_env, void *data, void *) {
784 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr module context is called");
785 delete static_cast<std::weak_ptr<Context> *>(data);
786 },
787 nullptr, nullptr);
788 if (res != napi_ok && workContext != nullptr) {
789 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
790 delete workContext;
791 return CreateJsUndefined(env);
792 }
793 return object;
794 }
795
CreateJSApplicationContext(napi_env env,const std::shared_ptr<ApplicationContext> applicationContext)796 napi_value JsBaseContext::CreateJSApplicationContext(napi_env env,
797 const std::shared_ptr<ApplicationContext> applicationContext)
798 {
799 napi_value value = JsApplicationContextUtils::CreateJsApplicationContext(env);
800 auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.ApplicationContext", &value, 1);
801 if (systemModule == nullptr) {
802 TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
803 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
804 return CreateJsUndefined(env);
805 }
806 napi_value object = systemModule->GetNapiValue();
807 if (!CheckTypeForNapiValue(env, object, napi_object)) {
808 TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
809 AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
810 return CreateJsUndefined(env);
811 }
812 auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(applicationContext);
813 napi_coerce_to_native_binding_object(
814 env, object, DetachCallbackFunc, AttachApplicationContext, workContext, nullptr);
815 auto res = napi_wrap(env, object, workContext,
816 [](napi_env, void *data, void *) {
817 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr application context is called");
818 delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
819 data = nullptr;
820 },
821 nullptr, nullptr);
822 if (res != napi_ok && workContext != nullptr) {
823 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
824 delete workContext;
825 return CreateJsUndefined(env);
826 }
827 napi_ref ref = nullptr;
828 napi_create_reference(env, object, 1, &ref);
829 ApplicationContextManager::GetApplicationContextManager()
830 .AddGlobalObject(env, std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(ref)));
831 applicationContext->SetApplicationInfoUpdateFlag(false);
832 return object;
833 }
834
CheckCallerIsSystemApp()835 bool JsBaseContext::CheckCallerIsSystemApp()
836 {
837 auto selfToken = IPCSkeleton::GetSelfTokenID();
838 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
839 return false;
840 }
841 return true;
842 }
843 } // namespace
844
AttachBaseContext(napi_env env,void * value,void * hint)845 napi_value AttachBaseContext(napi_env env, void* value, void* hint)
846 {
847 TAG_LOGD(AAFwkTag::APPKIT, "called");
848 if (value == nullptr || env == nullptr) {
849 TAG_LOGW(AAFwkTag::APPKIT, "invalid parameter");
850 return nullptr;
851 }
852 auto ptr = reinterpret_cast<std::weak_ptr<Context>*>(value)->lock();
853 if (ptr == nullptr) {
854 TAG_LOGW(AAFwkTag::APPKIT, "null ptr");
855 return nullptr;
856 }
857 napi_value object = CreateJsBaseContext(env, ptr, true);
858 auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &object, 1);
859 if (systemModule == nullptr) {
860 TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
861 return nullptr;
862 }
863
864 napi_value contextObj = systemModule->GetNapiValue();
865 if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
866 TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
867 return nullptr;
868 }
869 auto workContext = new (std::nothrow) std::weak_ptr<Context>(ptr);
870 napi_coerce_to_native_binding_object(
871 env, contextObj, DetachNewBaseContext, AttachBaseContext, workContext, nullptr);
872 napi_add_detached_finalizer(env, contextObj, DetachFinalizeBaseContext, nullptr);
873 auto res = napi_wrap(env, contextObj, workContext,
874 [](napi_env, void *data, void *) {
875 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr base context is called");
876 delete static_cast<std::weak_ptr<Context> *>(data);
877 },
878 nullptr, nullptr);
879 if (res != napi_ok && workContext != nullptr) {
880 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
881 delete workContext;
882 return nullptr;
883 }
884 return contextObj;
885 }
886
AttachApplicationContext(napi_env env,void * value,void * hint)887 napi_value AttachApplicationContext(napi_env env, void* value, void* hint)
888 {
889 TAG_LOGD(AAFwkTag::APPKIT, "called");
890 if (value == nullptr || env == nullptr) {
891 TAG_LOGW(AAFwkTag::APPKIT, "invalid parameter");
892 return nullptr;
893 }
894 auto ptr = reinterpret_cast<std::weak_ptr<ApplicationContext>*>(value)->lock();
895 if (ptr == nullptr) {
896 TAG_LOGW(AAFwkTag::APPKIT, "null ptr");
897 return nullptr;
898 }
899 napi_value object = JsApplicationContextUtils::CreateJsApplicationContext(env);
900 auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.ApplicationContext", &object, 1);
901 if (systemModule == nullptr) {
902 TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
903 return nullptr;
904 }
905 auto contextObj = systemModule->GetNapiValue();
906 if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
907 TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
908 return nullptr;
909 }
910 auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(ptr);
911 napi_coerce_to_native_binding_object(
912 env, contextObj, DetachNewApplicationContext, AttachApplicationContext, workContext, nullptr);
913 napi_add_detached_finalizer(env, contextObj, DetachFinalizeApplicationContext, nullptr);
914 auto res = napi_wrap(env, contextObj, workContext,
915 [](napi_env, void *data, void *) {
916 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr application context is called");
917 delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
918 data = nullptr;
919 },
920 nullptr, nullptr);
921 if (res != napi_ok && workContext != nullptr) {
922 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
923 delete workContext;
924 return nullptr;
925 }
926 return contextObj;
927 }
928
BindPropertyAndFunction(napi_env env,napi_value object,const char * moduleName)929 void BindPropertyAndFunction(napi_env env, napi_value object, const char* moduleName)
930 {
931 BindNativeProperty(env, object, "cacheDir", JsBaseContext::GetCacheDir);
932 BindNativeProperty(env, object, "tempDir", JsBaseContext::GetTempDir);
933 BindNativeProperty(env, object, "resourceDir", JsBaseContext::GetResourceDir);
934 BindNativeProperty(env, object, "filesDir", JsBaseContext::GetFilesDir);
935 BindNativeProperty(env, object, "distributedFilesDir", JsBaseContext::GetDistributedFilesDir);
936 BindNativeProperty(env, object, "databaseDir", JsBaseContext::GetDatabaseDir);
937 BindNativeProperty(env, object, "preferencesDir", JsBaseContext::GetPreferencesDir);
938 BindNativeProperty(env, object, "bundleCodeDir", JsBaseContext::GetBundleCodeDir);
939 BindNativeProperty(env, object, "cloudFileDir", JsBaseContext::GetCloudFileDir);
940 BindNativeProperty(env, object, "area", JsBaseContext::GetArea);
941 BindNativeProperty(env, object, "processName", JsBaseContext::GetProcessName);
942
943 BindNativeFunction(env, object, "createBundleContext", moduleName, JsBaseContext::CreateBundleContext);
944 BindNativeFunction(env, object, "getApplicationContext", moduleName, JsBaseContext::GetApplicationContext);
945 BindNativeFunction(env, object, "switchArea", moduleName, JsBaseContext::SwitchArea);
946 BindNativeFunction(env, object, "getArea", moduleName, JsBaseContext::GetArea);
947 BindNativeFunction(env, object, "createModuleContext", moduleName, JsBaseContext::CreateModuleContext);
948 BindNativeFunction(env, object, "createSystemHspModuleResourceManager", moduleName,
949 JsBaseContext::CreateSystemHspModuleResourceManager);
950 BindNativeFunction(env, object, "createModuleResourceManager", moduleName,
951 JsBaseContext::CreateModuleResourceManager);
952 BindNativeFunction(env, object, "getGroupDir", moduleName, JsBaseContext::GetGroupDir);
953 BindNativeFunction(env, object, "createAreaModeContext", moduleName, JsBaseContext::CreateAreaModeContext);
954 BindNativeFunction(env, object, "createDisplayContext", moduleName, JsBaseContext::CreateDisplayContext);
955 }
CreateJsBaseContext(napi_env env,std::shared_ptr<Context> context,bool keepContext)956 napi_value CreateJsBaseContext(napi_env env, std::shared_ptr<Context> context, bool keepContext)
957 {
958 napi_value object = nullptr;
959 napi_create_object(env, &object);
960 if (object == nullptr) {
961 TAG_LOGW(AAFwkTag::APPKIT, "null object");
962 return nullptr;
963 }
964 if (context == nullptr) {
965 TAG_LOGE(AAFwkTag::APPKIT, "null context");
966 return nullptr;
967 }
968 auto jsContext = std::make_unique<JsBaseContext>(context);
969 SetNamedNativePointer(env, object, BASE_CONTEXT_NAME, jsContext.release(), JsBaseContext::Finalizer);
970
971 auto appInfo = context->GetApplicationInfo();
972 if (appInfo != nullptr) {
973 napi_set_named_property(env, object, "applicationInfo", CreateJsApplicationInfo(env, *appInfo));
974 }
975 auto hapModuleInfo = context->GetHapModuleInfo();
976 if (hapModuleInfo != nullptr) {
977 napi_set_named_property(env, object, "currentHapModuleInfo", CreateJsHapModuleInfo(env, *hapModuleInfo));
978 }
979 auto resourceManager = context->GetResourceManager();
980 if (resourceManager != nullptr) {
981 auto jsResourceManager = CreateJsResourceManager(env, resourceManager, context);
982 if (jsResourceManager != nullptr) {
983 napi_set_named_property(env, object, "resourceManager", jsResourceManager);
984 } else {
985 TAG_LOGE(AAFwkTag::APPKIT, "null jsResourceManager");
986 }
987 }
988
989 const char *moduleName = "JsBaseContext";
990 BindPropertyAndFunction(env, object, moduleName);
991 return object;
992 }
993 } // namespace AbilityRuntime
994 } // namespace OHOS
995