• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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