• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 <iostream>
19 
20 #include "ability_runtime_error_util.h"
21 #include "context_impl.h"
22 #include "hilog_tag_wrapper.h"
23 #include "js_application_context_utils.h"
24 #include "js_data_converter.h"
25 #include "js_error_utils.h"
26 #include "js_resource_manager_utils.h"
27 #include "js_runtime_utils.h"
28 
29 namespace OHOS {
30 namespace AbilityRuntime {
31 namespace {
32 constexpr char BASE_CONTEXT_NAME[] = "__base_context_ptr__";
33 
DetachNewBaseContext(napi_env,void * nativeObject,void *)34 void *DetachNewBaseContext(napi_env, void *nativeObject, void *)
35 {
36     auto *origContext = static_cast<std::weak_ptr<Context> *>(nativeObject);
37     if (origContext == nullptr) {
38         TAG_LOGE(AAFwkTag::ABILITY_SIM, "origContext is null");
39         return nullptr;
40     }
41     TAG_LOGD(AAFwkTag::ABILITY_SIM, "New detached base context");
42     auto *detachNewContext = new (std::nothrow) std::weak_ptr<Context>(*origContext);
43     return detachNewContext;
44 }
45 
DetachFinalizeBaseContext(void * detachedObject,void *)46 void DetachFinalizeBaseContext(void *detachedObject, void *)
47 {
48     TAG_LOGD(AAFwkTag::ABILITY_SIM, "Finalizer detached base context");
49     delete static_cast<std::weak_ptr<Context> *>(detachedObject);
50 }
51 
52 class JsBaseContext {
53 public:
JsBaseContext(std::weak_ptr<Context> && context)54     explicit JsBaseContext(std::weak_ptr<Context> &&context) : context_(std::move(context)) {}
55     virtual ~JsBaseContext() = default;
56 
57     static void Finalizer(napi_env env, void *data, void *hint);
58     static napi_value CreateBundleContext(napi_env env, napi_callback_info info);
59     static napi_value GetApplicationContext(napi_env env, napi_callback_info info);
60     static napi_value SwitchArea(napi_env env, napi_callback_info info);
61     static napi_value GetArea(napi_env env, napi_callback_info info);
62     static napi_value CreateModuleContext(napi_env env, napi_callback_info info);
63     static napi_value CreateModuleResourceManager(napi_env env, napi_callback_info info);
64 
65     static napi_value GetCacheDir(napi_env env, napi_callback_info info);
66     static napi_value GetTempDir(napi_env env, napi_callback_info info);
67     static napi_value GetResourceDir(napi_env env, napi_callback_info info);
68     static napi_value GetFilesDir(napi_env env, napi_callback_info info);
69     static napi_value GetDistributedFilesDir(napi_env env, napi_callback_info info);
70     static napi_value GetDatabaseDir(napi_env env, napi_callback_info info);
71     static napi_value GetPreferencesDir(napi_env env, napi_callback_info info);
72     static napi_value GetBundleCodeDir(napi_env env, napi_callback_info info);
73     static napi_value GetCloudFileDir(napi_env env, napi_callback_info info);
74 
75     napi_value OnGetCacheDir(napi_env env, NapiCallbackInfo &info);
76     napi_value OnGetTempDir(napi_env env, NapiCallbackInfo &info);
77     napi_value OnGetResourceDir(napi_env env, NapiCallbackInfo &info);
78     napi_value OnGetFilesDir(napi_env env, NapiCallbackInfo &info);
79     napi_value OnGetDistributedFilesDir(napi_env env, NapiCallbackInfo &info);
80     napi_value OnGetDatabaseDir(napi_env env, NapiCallbackInfo &info);
81     napi_value OnGetPreferencesDir(napi_env env, NapiCallbackInfo &info);
82     napi_value OnGetBundleCodeDir(napi_env env, NapiCallbackInfo &info);
83     napi_value OnGetCloudFileDir(napi_env env, NapiCallbackInfo &info);
84     napi_value OnSwitchArea(napi_env env, NapiCallbackInfo &info);
85     napi_value OnGetArea(napi_env env, NapiCallbackInfo &info);
86     napi_value OnGetApplicationContext(napi_env env, NapiCallbackInfo &info);
87 
88 protected:
89     std::weak_ptr<Context> context_;
90 
91 private:
92     napi_value CreateJsModuleContext(napi_env env, const std::shared_ptr<Context> &moduleContext);
93     napi_value OnCreateModuleContext(napi_env env, NapiCallbackInfo &info);
94     bool CheckCallerIsSystemApp();
95 };
96 
Finalizer(napi_env env,void * data,void * hint)97 void JsBaseContext::Finalizer(napi_env env, void *data, void *hint)
98 {
99     TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
100     std::unique_ptr<JsBaseContext>(static_cast<JsBaseContext*>(data));
101 }
102 
CreateBundleContext(napi_env env,napi_callback_info info)103 napi_value JsBaseContext::CreateBundleContext(napi_env env, napi_callback_info info)
104 {
105     return nullptr;
106 }
107 
GetApplicationContext(napi_env env,napi_callback_info info)108 napi_value JsBaseContext::GetApplicationContext(napi_env env, napi_callback_info info)
109 {
110     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetApplicationContext, BASE_CONTEXT_NAME);
111 }
112 
SwitchArea(napi_env env,napi_callback_info info)113 napi_value JsBaseContext::SwitchArea(napi_env env, napi_callback_info info)
114 {
115     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnSwitchArea, BASE_CONTEXT_NAME);
116 }
117 
OnSwitchArea(napi_env env,NapiCallbackInfo & info)118 napi_value JsBaseContext::OnSwitchArea(napi_env env, NapiCallbackInfo &info)
119 {
120     if (info.argc == 0) {
121         TAG_LOGE(AAFwkTag::ABILITY_SIM, "invalid argc");
122         return CreateJsUndefined(env);
123     }
124 
125     auto context = context_.lock();
126     if (!context) {
127         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
128         return CreateJsUndefined(env);
129     }
130 
131     int mode = 0;
132     if (!ConvertFromJsValue(env, info.argv[0], mode)) {
133         TAG_LOGE(AAFwkTag::ABILITY_SIM, "Parse mode failed");
134         return CreateJsUndefined(env);
135     }
136 
137     context->SwitchArea(mode);
138 
139     napi_value object = info.thisVar;
140     if (object == nullptr) {
141         TAG_LOGE(AAFwkTag::ABILITY_SIM, "null object");
142         return CreateJsUndefined(env);
143     }
144     BindNativeProperty(env, object, "cacheDir", GetCacheDir);
145     BindNativeProperty(env, object, "tempDir", GetTempDir);
146     BindNativeProperty(env, object, "resourceDir", GetResourceDir);
147     BindNativeProperty(env, object, "filesDir", GetFilesDir);
148     BindNativeProperty(env, object, "distributedFilesDir", GetDistributedFilesDir);
149     BindNativeProperty(env, object, "databaseDir", GetDatabaseDir);
150     BindNativeProperty(env, object, "preferencesDir", GetPreferencesDir);
151     BindNativeProperty(env, object, "bundleCodeDir", GetBundleCodeDir);
152     BindNativeProperty(env, object, "cloudFileDir", GetCloudFileDir);
153     return CreateJsUndefined(env);
154 }
155 
CreateModuleContext(napi_env env,napi_callback_info info)156 napi_value JsBaseContext::CreateModuleContext(napi_env env, napi_callback_info info)
157 {
158     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateModuleContext, BASE_CONTEXT_NAME);
159 }
OnCreateModuleContext(napi_env env,NapiCallbackInfo & info)160 napi_value JsBaseContext::OnCreateModuleContext(napi_env env, NapiCallbackInfo &info)
161 {
162     auto context = context_.lock();
163     if (!context) {
164         TAG_LOGW(AAFwkTag::ABILITY_SIM, "null context");
165         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
166         return CreateJsUndefined(env);
167     }
168     std::shared_ptr<Context> moduleContext = nullptr;
169     std::string moduleName;
170     if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
171         TAG_LOGD(AAFwkTag::ABILITY_SIM, "Parse inner module name");
172         if (!ConvertFromJsValue(env, info.argv[0], moduleName)) {
173             TAG_LOGE(AAFwkTag::ABILITY_SIM, "Parse moduleName failed");
174             ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
175             return CreateJsUndefined(env);
176         }
177         moduleContext = context->CreateModuleContext(moduleName);
178     } else {
179         std::string bundleName;
180         if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
181             TAG_LOGE(AAFwkTag::ABILITY_SIM, "Parse bundleName failed");
182             ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
183             return CreateJsUndefined(env);
184         }
185         if (!CheckCallerIsSystemApp()) {
186             TAG_LOGE(AAFwkTag::ABILITY_SIM, "not system-app");
187             AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
188             return CreateJsUndefined(env);
189         }
190         TAG_LOGD(AAFwkTag::ABILITY_SIM, "Parse outer module name");
191         moduleContext = context->CreateModuleContext(bundleName, moduleName);
192     }
193     if (!moduleContext) {
194         TAG_LOGE(AAFwkTag::ABILITY_SIM, "null moduleContext");
195         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
196         return CreateJsUndefined(env);
197     }
198     return CreateJsModuleContext(env, moduleContext);
199 }
200 
CreateJsModuleContext(napi_env env,const std::shared_ptr<Context> & moduleContext)201 napi_value JsBaseContext::CreateJsModuleContext(napi_env env, const std::shared_ptr<Context> &moduleContext)
202 {
203     napi_value value = CreateJsBaseContext(env, moduleContext, true);
204 
205     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
206     if (systemModule == nullptr) {
207         TAG_LOGW(AAFwkTag::ABILITY_SIM, "null systemModule");
208         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
209         return CreateJsUndefined(env);
210     }
211     napi_value object = systemModule->GetNapiValue();
212     if (!CheckTypeForNapiValue(env, object, napi_object)) {
213         TAG_LOGE(AAFwkTag::ABILITY_SIM, "get object failed");
214         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
215         return CreateJsUndefined(env);
216     }
217     auto workContext = new (std::nothrow) std::weak_ptr<Context>(moduleContext);
218     napi_coerce_to_native_binding_object(env, object, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
219     auto res = napi_wrap(env, object, workContext,
220         [](napi_env, void *data, void *) {
221             TAG_LOGD(AAFwkTag::ABILITY_SIM, "Finalizer for weak_ptr module context is called");
222             delete static_cast<std::weak_ptr<Context> *>(data);
223         },
224         nullptr, nullptr);
225     if (res != napi_ok && workContext != nullptr) {
226         TAG_LOGE(AAFwkTag::ABILITY_SIM, "napi_wrap failed:%{public}d", res);
227         delete workContext;
228         return CreateJsUndefined(env);
229     }
230     return object;
231 }
232 
CreateModuleResourceManager(napi_env env,napi_callback_info info)233 napi_value JsBaseContext::CreateModuleResourceManager(napi_env env, napi_callback_info info)
234 {
235     return nullptr;
236 }
237 
GetArea(napi_env env,napi_callback_info info)238 napi_value JsBaseContext::GetArea(napi_env env, napi_callback_info info)
239 {
240     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetArea, BASE_CONTEXT_NAME);
241 }
242 
OnGetArea(napi_env env,NapiCallbackInfo & info)243 napi_value JsBaseContext::OnGetArea(napi_env env, NapiCallbackInfo &info)
244 {
245     auto context = context_.lock();
246     if (!context) {
247         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
248         return CreateJsUndefined(env);
249     }
250     int area = context->GetArea();
251     return CreateJsValue(env, area);
252 }
253 
GetCacheDir(napi_env env,napi_callback_info info)254 napi_value JsBaseContext::GetCacheDir(napi_env env, napi_callback_info info)
255 {
256     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetCacheDir, BASE_CONTEXT_NAME);
257 }
258 
OnGetCacheDir(napi_env env,NapiCallbackInfo & info)259 napi_value JsBaseContext::OnGetCacheDir(napi_env env, NapiCallbackInfo &info)
260 {
261     auto context = context_.lock();
262     if (!context) {
263         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
264         return CreateJsUndefined(env);
265     }
266     std::string path = context->GetCacheDir();
267     return CreateJsValue(env, path);
268 }
269 
GetTempDir(napi_env env,napi_callback_info info)270 napi_value JsBaseContext::GetTempDir(napi_env env, napi_callback_info info)
271 {
272     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetTempDir, BASE_CONTEXT_NAME);
273 }
274 
OnGetTempDir(napi_env env,NapiCallbackInfo & info)275 napi_value JsBaseContext::OnGetTempDir(napi_env env, NapiCallbackInfo &info)
276 {
277     auto context = context_.lock();
278     if (!context) {
279         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
280         return CreateJsUndefined(env);
281     }
282     std::string path = context->GetTempDir();
283     return CreateJsValue(env, path);
284 }
285 
GetResourceDir(napi_env env,napi_callback_info info)286 napi_value JsBaseContext::GetResourceDir(napi_env env, napi_callback_info info)
287 {
288     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetResourceDir, BASE_CONTEXT_NAME);
289 }
290 
OnGetResourceDir(napi_env env,NapiCallbackInfo & info)291 napi_value JsBaseContext::OnGetResourceDir(napi_env env, NapiCallbackInfo &info)
292 {
293     auto context = context_.lock();
294     if (!context) {
295         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
296         return CreateJsUndefined(env);
297     }
298     std::string path = context->GetResourceDir();
299     return CreateJsValue(env, path);
300 }
301 
GetFilesDir(napi_env env,napi_callback_info info)302 napi_value JsBaseContext::GetFilesDir(napi_env env, napi_callback_info info)
303 {
304     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetFilesDir, BASE_CONTEXT_NAME);
305 }
306 
OnGetFilesDir(napi_env env,NapiCallbackInfo & info)307 napi_value JsBaseContext::OnGetFilesDir(napi_env env, NapiCallbackInfo &info)
308 {
309     auto context = context_.lock();
310     if (!context) {
311         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
312         return CreateJsUndefined(env);
313     }
314     std::string path = context->GetFilesDir();
315     return CreateJsValue(env, path);
316 }
317 
GetDistributedFilesDir(napi_env env,napi_callback_info info)318 napi_value JsBaseContext::GetDistributedFilesDir(napi_env env, napi_callback_info info)
319 {
320     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetDistributedFilesDir, BASE_CONTEXT_NAME);
321 }
322 
OnGetDistributedFilesDir(napi_env env,NapiCallbackInfo & info)323 napi_value JsBaseContext::OnGetDistributedFilesDir(napi_env env, NapiCallbackInfo &info)
324 {
325     auto context = context_.lock();
326     if (!context) {
327         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
328         return CreateJsUndefined(env);
329     }
330     std::string path = context->GetDistributedFilesDir();
331     return CreateJsValue(env, path);
332 }
333 
GetDatabaseDir(napi_env env,napi_callback_info info)334 napi_value JsBaseContext::GetDatabaseDir(napi_env env, napi_callback_info info)
335 {
336     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetDatabaseDir, BASE_CONTEXT_NAME);
337 }
338 
OnGetDatabaseDir(napi_env env,NapiCallbackInfo & info)339 napi_value JsBaseContext::OnGetDatabaseDir(napi_env env, NapiCallbackInfo &info)
340 {
341     auto context = context_.lock();
342     if (!context) {
343         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
344         return CreateJsUndefined(env);
345     }
346     std::string path = context->GetDatabaseDir();
347     return CreateJsValue(env, path);
348 }
349 
GetPreferencesDir(napi_env env,napi_callback_info info)350 napi_value JsBaseContext::GetPreferencesDir(napi_env env, napi_callback_info info)
351 {
352     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetPreferencesDir, BASE_CONTEXT_NAME);
353 }
354 
OnGetPreferencesDir(napi_env env,NapiCallbackInfo & info)355 napi_value JsBaseContext::OnGetPreferencesDir(napi_env env, NapiCallbackInfo &info)
356 {
357     auto context = context_.lock();
358     if (!context) {
359         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
360         return CreateJsUndefined(env);
361     }
362     std::string path = context->GetPreferencesDir();
363     return CreateJsValue(env, path);
364 }
365 
GetBundleCodeDir(napi_env env,napi_callback_info info)366 napi_value JsBaseContext::GetBundleCodeDir(napi_env env, napi_callback_info info)
367 {
368     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetBundleCodeDir, BASE_CONTEXT_NAME);
369 }
370 
OnGetBundleCodeDir(napi_env env,NapiCallbackInfo & info)371 napi_value JsBaseContext::OnGetBundleCodeDir(napi_env env, NapiCallbackInfo &info)
372 {
373     auto context = context_.lock();
374     if (!context) {
375         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
376         return CreateJsUndefined(env);
377     }
378     std::string path = context->GetBundleCodeDir();
379     return CreateJsValue(env, path);
380 }
381 
GetCloudFileDir(napi_env env,napi_callback_info info)382 napi_value JsBaseContext::GetCloudFileDir(napi_env env, napi_callback_info info)
383 {
384     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetCloudFileDir, BASE_CONTEXT_NAME);
385 }
386 
OnGetCloudFileDir(napi_env env,NapiCallbackInfo & info)387 napi_value JsBaseContext::OnGetCloudFileDir(napi_env env, NapiCallbackInfo &info)
388 {
389     auto context = context_.lock();
390     if (!context) {
391         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
392         return CreateJsUndefined(env);
393     }
394     std::string path = context->GetCloudFileDir();
395     return CreateJsValue(env, path);
396 }
397 
OnGetApplicationContext(napi_env env,NapiCallbackInfo & info)398 napi_value JsBaseContext::OnGetApplicationContext(napi_env env, NapiCallbackInfo &info)
399 {
400     TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
401     napi_value value = JsApplicationContextUtils::CreateJsApplicationContext(env, context_.lock());
402     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.ApplicationContext", &value, 1);
403     if (systemModule == nullptr) {
404         return CreateJsUndefined(env);
405     }
406     auto contextObj =  systemModule->GetNapiValue();
407     return contextObj;
408 }
409 
CheckCallerIsSystemApp()410 bool JsBaseContext::CheckCallerIsSystemApp()
411 {
412     return true;
413 }
414 } // namespace
415 
CreateJsBaseContext(napi_env env,std::shared_ptr<Context> context,bool keepContext)416 napi_value CreateJsBaseContext(napi_env env, std::shared_ptr<Context> context, bool keepContext)
417 {
418     napi_value object = nullptr;
419     napi_create_object(env, &object);
420     if (object == nullptr) {
421         TAG_LOGW(AAFwkTag::ABILITY_SIM, "null object");
422         return object;
423     }
424 
425     auto appInfo = context->GetApplicationInfo();
426     if (appInfo != nullptr) {
427         napi_set_named_property(env, object, "applicationInfo", CreateJsApplicationInfo(env, *appInfo));
428     }
429     auto hapModuleInfo = context->GetHapModuleInfo();
430     if (hapModuleInfo != nullptr) {
431         napi_set_named_property(env, object, "currentHapModuleInfo", CreateJsHapModuleInfo(env, *hapModuleInfo));
432     }
433 
434     auto resourceManager = context->GetResourceManager();
435     if (resourceManager != nullptr) {
436         auto jsResourceManager = CreateJsResourceManager(env, resourceManager, context);
437         if (jsResourceManager != nullptr) {
438             napi_set_named_property(env, object, "resourceManager", jsResourceManager);
439         } else {
440             TAG_LOGE(AAFwkTag::ABILITY_SIM, "null jsResourceManager");
441         }
442     }
443 
444     auto jsContext = std::make_unique<JsBaseContext>(context);
445     SetNamedNativePointer(env, object, BASE_CONTEXT_NAME, jsContext.release(), JsBaseContext::Finalizer);
446 
447     BindNativeProperty(env, object, "cacheDir", JsBaseContext::GetCacheDir);
448     BindNativeProperty(env, object, "tempDir", JsBaseContext::GetTempDir);
449     BindNativeProperty(env, object, "resourceDir", JsBaseContext::GetResourceDir);
450     BindNativeProperty(env, object, "filesDir", JsBaseContext::GetFilesDir);
451     BindNativeProperty(env, object, "distributedFilesDir", JsBaseContext::GetDistributedFilesDir);
452     BindNativeProperty(env, object, "databaseDir", JsBaseContext::GetDatabaseDir);
453     BindNativeProperty(env, object, "preferencesDir", JsBaseContext::GetPreferencesDir);
454     BindNativeProperty(env, object, "bundleCodeDir", JsBaseContext::GetBundleCodeDir);
455     BindNativeProperty(env, object, "cloudFileDir", JsBaseContext::GetCloudFileDir);
456     BindNativeProperty(env, object, "area", JsBaseContext::GetArea);
457     const char *moduleName = "JsBaseContext";
458     BindNativeFunction(env, object, "createBundleContext", moduleName, JsBaseContext::CreateBundleContext);
459     BindNativeFunction(env, object, "getApplicationContext", moduleName, JsBaseContext::GetApplicationContext);
460     BindNativeFunction(env, object, "switchArea", moduleName, JsBaseContext::SwitchArea);
461     BindNativeFunction(env, object, "getArea", moduleName, JsBaseContext::GetArea);
462     BindNativeFunction(env, object, "createModuleContext", moduleName, JsBaseContext::CreateModuleContext);
463     BindNativeFunction(env, object, "createModuleResourceManager", moduleName,
464         JsBaseContext::CreateModuleResourceManager);
465 
466     return object;
467 }
468 
AttachBaseContext(napi_env env,void * value,void * hint)469 napi_value AttachBaseContext(napi_env env, void *value, void *hint)
470 {
471     TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
472     if (value == nullptr || env == nullptr) {
473         TAG_LOGW(AAFwkTag::ABILITY_SIM, "invalid parameter");
474         return nullptr;
475     }
476     auto ptr = reinterpret_cast<std::weak_ptr<Context> *>(value)->lock();
477     if (ptr == nullptr) {
478         TAG_LOGW(AAFwkTag::ABILITY_SIM, "null ptr");
479         return nullptr;
480     }
481     napi_value object = CreateJsBaseContext(env, ptr, true);
482     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &object, 1);
483     if (systemModule == nullptr) {
484         TAG_LOGW(AAFwkTag::ABILITY_SIM, "null systemModule");
485         return nullptr;
486     }
487 
488     napi_value contextObj = systemModule->GetNapiValue();
489     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
490         TAG_LOGE(AAFwkTag::ABILITY_SIM, "get object failed");
491         return nullptr;
492     }
493     auto workContext = new (std::nothrow) std::weak_ptr<Context>(ptr);
494     napi_coerce_to_native_binding_object(
495         env, contextObj, DetachNewBaseContext, AttachBaseContext, workContext, nullptr);
496     napi_add_detached_finalizer(env, contextObj, DetachFinalizeBaseContext, nullptr);
497     auto res = napi_wrap(env, contextObj, workContext,
498         [](napi_env, void *data, void *) {
499             TAG_LOGD(AAFwkTag::ABILITY_SIM, "Finalizer for weak_ptr base context is called");
500             delete static_cast<std::weak_ptr<Context> *>(data);
501         },
502         nullptr, nullptr);
503     if (res != napi_ok && workContext != nullptr) {
504         TAG_LOGE(AAFwkTag::ABILITY_SIM, "napi_wrap failed:%{public}d", res);
505         delete workContext;
506         return nullptr;
507     }
508     return contextObj;
509 }
510 } // namespace AbilityRuntime
511 } // namespace OHOS
512