• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_context_utils.h"
17 
18 #include "ability_runtime_error_util.h"
19 #include "hilog_wrapper.h"
20 #include "js_application_context_utils.h"
21 #include "js_data_struct_converter.h"
22 #include "js_hap_module_info_utils.h"
23 #include "js_resource_manager_utils.h"
24 #include "js_runtime_utils.h"
25 #include "application_context.h"
26 
27 namespace OHOS {
28 namespace AbilityRuntime {
29 namespace {
30 constexpr char BASE_CONTEXT_NAME[] = "__base_context_ptr__";
31 
32 class JsBaseContext {
33 public:
JsBaseContext(std::weak_ptr<Context> && context)34     explicit JsBaseContext(std::weak_ptr<Context>&& context) : context_(std::move(context)) {}
35     virtual ~JsBaseContext() = default;
36 
37     static void Finalizer(NativeEngine* engine, void* data, void* hint);
38     static NativeValue* CreateBundleContext(NativeEngine* engine, NativeCallbackInfo* info);
39     static NativeValue* GetApplicationContext(NativeEngine* engine, NativeCallbackInfo* info);
40     static NativeValue* SwitchArea(NativeEngine* engine, NativeCallbackInfo* info);
41     static NativeValue* GetArea(NativeEngine* engine, NativeCallbackInfo* info);
42     static NativeValue* CreateModuleContext(NativeEngine* engine, NativeCallbackInfo* info);
43 
44     NativeValue* OnGetCacheDir(NativeEngine& engine, NativeCallbackInfo& info);
45     NativeValue* OnGetTempDir(NativeEngine& engine, NativeCallbackInfo& info);
46     NativeValue* OnGetFilesDir(NativeEngine& engine, NativeCallbackInfo& info);
47     NativeValue* OnGetDistributedFilesDir(NativeEngine& engine, NativeCallbackInfo& info);
48     NativeValue* OnGetDatabaseDir(NativeEngine& engine, NativeCallbackInfo& info);
49     NativeValue* OnGetPreferencesDir(NativeEngine& engine, NativeCallbackInfo& info);
50     NativeValue* OnGetBundleCodeDir(NativeEngine& engine, NativeCallbackInfo& info);
51 
52     static NativeValue* GetCacheDir(NativeEngine* engine, NativeCallbackInfo* info);
53     static NativeValue* GetTempDir(NativeEngine* engine, NativeCallbackInfo* info);
54     static NativeValue* GetFilesDir(NativeEngine* engine, NativeCallbackInfo* info);
55     static NativeValue* GetDistributedFilesDir(NativeEngine* engine, NativeCallbackInfo* info);
56     static NativeValue* GetDatabaseDir(NativeEngine* engine, NativeCallbackInfo* info);
57     static NativeValue* GetPreferencesDir(NativeEngine* engine, NativeCallbackInfo* info);
58     static NativeValue* GetBundleCodeDir(NativeEngine* engine, NativeCallbackInfo* info);
59 
60 protected:
61     std::weak_ptr<Context> context_;
62 
63 private:
64     NativeValue* OnCreateBundleContext(NativeEngine& engine, NativeCallbackInfo& info);
65     NativeValue* OnGetApplicationContext(NativeEngine& engine, NativeCallbackInfo& info);
66     NativeValue* OnSwitchArea(NativeEngine& engine, NativeCallbackInfo& info);
67     NativeValue* OnGetArea(NativeEngine& engine, NativeCallbackInfo& info);
68     NativeValue* OnCreateModuleContext(NativeEngine& engine, NativeCallbackInfo& info);
69 };
70 
Finalizer(NativeEngine * engine,void * data,void * hint)71 void JsBaseContext::Finalizer(NativeEngine* engine, void* data, void* hint)
72 {
73     HILOG_DEBUG("JsBaseContext::Finalizer is called");
74     std::unique_ptr<JsBaseContext>(static_cast<JsBaseContext*>(data));
75 }
76 
CreateBundleContext(NativeEngine * engine,NativeCallbackInfo * info)77 NativeValue* JsBaseContext::CreateBundleContext(NativeEngine* engine, NativeCallbackInfo* info)
78 {
79     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
80     return me != nullptr ? me->OnCreateBundleContext(*engine, *info) : nullptr;
81 }
82 
GetApplicationContext(NativeEngine * engine,NativeCallbackInfo * info)83 NativeValue* JsBaseContext::GetApplicationContext(NativeEngine* engine, NativeCallbackInfo* info)
84 {
85     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
86     return me != nullptr ? me->OnGetApplicationContext(*engine, *info) : nullptr;
87 }
88 
SwitchArea(NativeEngine * engine,NativeCallbackInfo * info)89 NativeValue* JsBaseContext::SwitchArea(NativeEngine* engine, NativeCallbackInfo* info)
90 {
91     HILOG_INFO("JsBaseContext::SwitchArea is called");
92     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
93     return me != nullptr ? me->OnSwitchArea(*engine, *info) : nullptr;
94 }
95 
OnSwitchArea(NativeEngine & engine,NativeCallbackInfo & info)96 NativeValue* JsBaseContext::OnSwitchArea(NativeEngine& engine, NativeCallbackInfo& info)
97 {
98     if (info.argc == 0) {
99         HILOG_ERROR("Not enough params");
100         return engine.CreateUndefined();
101     }
102 
103     auto context = context_.lock();
104     if (!context) {
105         HILOG_WARN("context is already released");
106         return engine.CreateUndefined();
107     }
108 
109     int mode = 0;
110     if (!ConvertFromJsValue(engine, info.argv[0], mode)) {
111         HILOG_ERROR("Parse mode failed");
112         return engine.CreateUndefined();
113     }
114 
115     context->SwitchArea(mode);
116 
117     NativeValue* thisVar = info.thisVar;
118     NativeObject* object = ConvertNativeValueTo<NativeObject>(thisVar);
119     if (object == nullptr) {
120         HILOG_ERROR("object is nullptr");
121         return engine.CreateUndefined();
122     }
123     BindNativeProperty(*object, "cacheDir", GetCacheDir);
124     BindNativeProperty(*object, "tempDir", GetTempDir);
125     BindNativeProperty(*object, "filesDir", GetFilesDir);
126     BindNativeProperty(*object, "distributedFilesDir", GetDistributedFilesDir);
127     BindNativeProperty(*object, "databaseDir", GetDatabaseDir);
128     BindNativeProperty(*object, "preferencesDir", GetPreferencesDir);
129     BindNativeProperty(*object, "bundleCodeDir", GetBundleCodeDir);
130     return engine.CreateUndefined();
131 }
132 
CreateModuleContext(NativeEngine * engine,NativeCallbackInfo * info)133 NativeValue* JsBaseContext::CreateModuleContext(NativeEngine* engine, NativeCallbackInfo* info)
134 {
135     HILOG_INFO("JsBaseContext::CreateModuleContext is called");
136     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
137     return me != nullptr ? me->OnCreateModuleContext(*engine, *info) : nullptr;
138 }
139 
OnCreateModuleContext(NativeEngine & engine,NativeCallbackInfo & info)140 NativeValue* JsBaseContext::OnCreateModuleContext(NativeEngine& engine, NativeCallbackInfo& info)
141 {
142     auto context = context_.lock();
143     if (!context) {
144         HILOG_WARN("context is already released");
145         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
146         return engine.CreateUndefined();
147     }
148 
149     std::shared_ptr<Context> moduleContext = nullptr;
150     std::string moduleName;
151 
152     if (!ConvertFromJsValue(engine, info.argv[1], moduleName)) {
153         HILOG_INFO("Parse inner module name.");
154         if (!ConvertFromJsValue(engine, info.argv[0], moduleName)) {
155             HILOG_ERROR("Parse moduleName failed");
156             AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
157             return engine.CreateUndefined();
158         }
159         moduleContext = context->CreateModuleContext(moduleName);
160     } else {
161         std::string bundleName;
162         if (!ConvertFromJsValue(engine, info.argv[0], bundleName)) {
163             HILOG_ERROR("Parse bundleName failed");
164             AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
165             return engine.CreateUndefined();
166         }
167         HILOG_INFO("Parse outer module name.");
168         moduleContext = context->CreateModuleContext(bundleName, moduleName);
169     }
170 
171     if (!moduleContext) {
172         HILOG_ERROR("failed to create module context.");
173         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
174         return engine.CreateUndefined();
175     }
176 
177     NativeValue* value = CreateJsBaseContext(engine, moduleContext, nullptr, nullptr, true);
178     auto systemModule = JsRuntime::LoadSystemModuleByEngine(&engine, "application.Context", &value, 1);
179     if (systemModule == nullptr) {
180         HILOG_WARN("invalid systemModule.");
181         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
182         return engine.CreateUndefined();
183     }
184     auto contextObj = systemModule->Get();
185     NativeObject *nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
186     if (nativeObj == nullptr) {
187         HILOG_ERROR("OnCreateModuleContext, Failed to get context native object");
188         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
189         return engine.CreateUndefined();
190     }
191     auto workContext = new (std::nothrow) std::weak_ptr<Context>(moduleContext);
192     nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
193     nativeObj->SetNativePointer(
194         workContext,
195         [](NativeEngine *, void *data, void *) {
196             HILOG_DEBUG("Finalizer for weak_ptr module context is called");
197             delete static_cast<std::weak_ptr<Context> *>(data);
198         },
199         nullptr);
200     return contextObj;
201 }
202 
GetArea(NativeEngine * engine,NativeCallbackInfo * info)203 NativeValue* JsBaseContext::GetArea(NativeEngine* engine, NativeCallbackInfo* info)
204 {
205     HILOG_INFO("JsBaseContext::GetArea is called");
206     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
207     return me != nullptr ? me->OnGetArea(*engine, *info) : nullptr;
208 }
209 
OnGetArea(NativeEngine & engine,NativeCallbackInfo & info)210 NativeValue* JsBaseContext::OnGetArea(NativeEngine& engine, NativeCallbackInfo& info)
211 {
212     auto context = context_.lock();
213     if (!context) {
214         HILOG_WARN("context is already released");
215         return engine.CreateUndefined();
216     }
217     int area = context->GetArea();
218     return engine.CreateNumber(area);
219 }
220 
GetCacheDir(NativeEngine * engine,NativeCallbackInfo * info)221 NativeValue* JsBaseContext::GetCacheDir(NativeEngine* engine, NativeCallbackInfo* info)
222 {
223     HILOG_INFO("JsBaseContext::GetCacheDir is called");
224     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
225     return me != nullptr ? me->OnGetCacheDir(*engine, *info) : nullptr;
226 }
227 
OnGetCacheDir(NativeEngine & engine,NativeCallbackInfo & info)228 NativeValue* JsBaseContext::OnGetCacheDir(NativeEngine& engine, NativeCallbackInfo& info)
229 {
230     auto context = context_.lock();
231     if (!context) {
232         HILOG_WARN("context is already released");
233         return engine.CreateUndefined();
234     }
235     std::string path = context->GetCacheDir();
236     return engine.CreateString(path.c_str(), path.length());
237 }
238 
GetTempDir(NativeEngine * engine,NativeCallbackInfo * info)239 NativeValue* JsBaseContext::GetTempDir(NativeEngine* engine, NativeCallbackInfo* info)
240 {
241     HILOG_INFO("JsBaseContext::GetTempDir is called");
242     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
243     return me != nullptr ? me->OnGetTempDir(*engine, *info) : nullptr;
244 }
245 
OnGetTempDir(NativeEngine & engine,NativeCallbackInfo & info)246 NativeValue* JsBaseContext::OnGetTempDir(NativeEngine& engine, NativeCallbackInfo& info)
247 {
248     auto context = context_.lock();
249     if (!context) {
250         HILOG_WARN("context is already released");
251         return engine.CreateUndefined();
252     }
253     std::string path = context->GetTempDir();
254     return engine.CreateString(path.c_str(), path.length());
255 }
256 
GetFilesDir(NativeEngine * engine,NativeCallbackInfo * info)257 NativeValue* JsBaseContext::GetFilesDir(NativeEngine* engine, NativeCallbackInfo* info)
258 {
259     HILOG_INFO("JsBaseContext::GetFilesDir is called");
260     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
261     return me != nullptr ? me->OnGetFilesDir(*engine, *info) : nullptr;
262 }
263 
OnGetFilesDir(NativeEngine & engine,NativeCallbackInfo & info)264 NativeValue* JsBaseContext::OnGetFilesDir(NativeEngine& engine, NativeCallbackInfo& info)
265 {
266     auto context = context_.lock();
267     if (!context) {
268         HILOG_WARN("context is already released");
269         return engine.CreateUndefined();
270     }
271     std::string path = context->GetFilesDir();
272     return engine.CreateString(path.c_str(), path.length());
273 }
274 
GetDistributedFilesDir(NativeEngine * engine,NativeCallbackInfo * info)275 NativeValue* JsBaseContext::GetDistributedFilesDir(NativeEngine* engine, NativeCallbackInfo* info)
276 {
277     HILOG_INFO("JsBaseContext::GetDistributedFilesDir is called");
278     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
279     return me != nullptr ? me->OnGetDistributedFilesDir(*engine, *info) : nullptr;
280 }
281 
OnGetDistributedFilesDir(NativeEngine & engine,NativeCallbackInfo & info)282 NativeValue* JsBaseContext::OnGetDistributedFilesDir(NativeEngine& engine, NativeCallbackInfo& info)
283 {
284     auto context = context_.lock();
285     if (!context) {
286         HILOG_WARN("context is already released");
287         return engine.CreateUndefined();
288     }
289     std::string path = context->GetDistributedFilesDir();
290     return engine.CreateString(path.c_str(), path.length());
291 }
292 
GetDatabaseDir(NativeEngine * engine,NativeCallbackInfo * info)293 NativeValue* JsBaseContext::GetDatabaseDir(NativeEngine* engine, NativeCallbackInfo* info)
294 {
295     HILOG_INFO("JsBaseContext::GetDatabaseDir is called");
296     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
297     return me != nullptr ? me->OnGetDatabaseDir(*engine, *info) : nullptr;
298 }
299 
OnGetDatabaseDir(NativeEngine & engine,NativeCallbackInfo & info)300 NativeValue* JsBaseContext::OnGetDatabaseDir(NativeEngine& engine, NativeCallbackInfo& info)
301 {
302     auto context = context_.lock();
303     if (!context) {
304         HILOG_WARN("context is already released");
305         return engine.CreateUndefined();
306     }
307     std::string path = context->GetDatabaseDir();
308     return engine.CreateString(path.c_str(), path.length());
309 }
310 
GetPreferencesDir(NativeEngine * engine,NativeCallbackInfo * info)311 NativeValue* JsBaseContext::GetPreferencesDir(NativeEngine* engine, NativeCallbackInfo* info)
312 {
313     HILOG_INFO("JsBaseContext::GetPreferencesDir is called");
314     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
315     return me != nullptr ? me->OnGetPreferencesDir(*engine, *info) : nullptr;
316 }
317 
OnGetPreferencesDir(NativeEngine & engine,NativeCallbackInfo & info)318 NativeValue* JsBaseContext::OnGetPreferencesDir(NativeEngine& engine, NativeCallbackInfo& info)
319 {
320     auto context = context_.lock();
321     if (!context) {
322         HILOG_WARN("context is already released");
323         return engine.CreateUndefined();
324     }
325     std::string path = context->GetPreferencesDir();
326     return engine.CreateString(path.c_str(), path.length());
327 }
328 
GetBundleCodeDir(NativeEngine * engine,NativeCallbackInfo * info)329 NativeValue* JsBaseContext::GetBundleCodeDir(NativeEngine* engine, NativeCallbackInfo* info)
330 {
331     HILOG_INFO("JsBaseContext::GetBundleCodeDir is called");
332     JsBaseContext* me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
333     return me != nullptr ? me->OnGetBundleCodeDir(*engine, *info) : nullptr;
334 }
335 
OnGetBundleCodeDir(NativeEngine & engine,NativeCallbackInfo & info)336 NativeValue* JsBaseContext::OnGetBundleCodeDir(NativeEngine& engine, NativeCallbackInfo& info)
337 {
338     auto context = context_.lock();
339     if (!context) {
340         HILOG_WARN("context is already released");
341         return engine.CreateUndefined();
342     }
343     std::string path = context->GetBundleCodeDir();
344     return engine.CreateString(path.c_str(), path.length());
345 }
346 
OnCreateBundleContext(NativeEngine & engine,NativeCallbackInfo & info)347 NativeValue* JsBaseContext::OnCreateBundleContext(NativeEngine& engine, NativeCallbackInfo& info)
348 {
349     if (info.argc == 0) {
350         HILOG_ERROR("Not enough params");
351         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
352         return engine.CreateUndefined();
353     }
354 
355     auto context = context_.lock();
356     if (!context) {
357         HILOG_WARN("context is already released");
358         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
359         return engine.CreateUndefined();
360     }
361 
362     std::string bundleName;
363     if (!ConvertFromJsValue(engine, info.argv[0], bundleName)) {
364         HILOG_ERROR("Parse bundleName failed");
365         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
366         return engine.CreateUndefined();
367     }
368 
369     auto bundleContext = context->CreateBundleContext(bundleName);
370     if (!bundleContext) {
371         HILOG_ERROR("bundleContext is nullptr");
372         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
373         return engine.CreateUndefined();
374     }
375 
376     NativeValue* value = CreateJsBaseContext(engine, bundleContext, nullptr, nullptr, true);
377     auto systemModule = JsRuntime::LoadSystemModuleByEngine(&engine, "application.Context", &value, 1);
378     if (systemModule == nullptr) {
379         HILOG_WARN("OnCreateBundleContext, invalid systemModule.");
380         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
381         return engine.CreateUndefined();
382     }
383     auto contextObj = systemModule->Get();
384     NativeObject *nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
385     if (nativeObj == nullptr) {
386         HILOG_ERROR("OnCreateBundleContext, Failed to get context native object");
387         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
388         return engine.CreateUndefined();
389     }
390     auto workContext = new (std::nothrow) std::weak_ptr<Context>(bundleContext);
391     nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
392     nativeObj->SetNativePointer(
393         workContext,
394         [](NativeEngine *, void *data, void *) {
395             HILOG_DEBUG("Finalizer for weak_ptr bundle context is called");
396             delete static_cast<std::weak_ptr<Context> *>(data);
397         },
398         nullptr);
399     return contextObj;
400 }
401 
OnGetApplicationContext(NativeEngine & engine,NativeCallbackInfo & info)402 NativeValue* JsBaseContext::OnGetApplicationContext(NativeEngine& engine, NativeCallbackInfo& info)
403 {
404     HILOG_INFO("GetApplicationContext start");
405     auto context = context_.lock();
406     if (!context) {
407         HILOG_WARN("context is already released");
408         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
409         return engine.CreateUndefined();
410     }
411 
412     auto applicationContext = Context::GetApplicationContext();
413     if (applicationContext == nullptr) {
414         HILOG_WARN("applicationContext is nullptr");
415         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
416         return engine.CreateUndefined();
417     }
418 
419     NativeValue* value = JsApplicationContextUtils::CreateJsApplicationContext(engine);
420     auto systemModule = JsRuntime::LoadSystemModuleByEngine(&engine, "application.ApplicationContext", &value, 1);
421     if (systemModule == nullptr) {
422         HILOG_WARN("OnGetApplicationContext, invalid systemModule.");
423         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
424         return engine.CreateUndefined();
425     }
426     auto contextObj = systemModule->Get();
427     NativeObject *nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
428     if (nativeObj == nullptr) {
429         HILOG_ERROR("OnGetApplicationContext, Failed to get context native object");
430         AbilityRuntimeErrorUtil::Throw(engine, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
431         return engine.CreateUndefined();
432     }
433     auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(applicationContext);
434     nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachApplicationContext,
435         workContext, nullptr);
436     nativeObj->SetNativePointer(
437         workContext,
438         [](NativeEngine *, void *data, void *) {
439             HILOG_DEBUG("Finalizer for weak_ptr application context is called");
440             delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
441         },
442         nullptr);
443     return contextObj;
444 }
445 } // namespace
446 
AttachBaseContext(NativeEngine * engine,void * value,void * hint)447 NativeValue* AttachBaseContext(NativeEngine* engine, void* value, void* hint)
448 {
449     HILOG_INFO("AttachBaseContext");
450     if (value == nullptr || engine == nullptr) {
451         HILOG_WARN("invalid parameter.");
452         return nullptr;
453     }
454     auto ptr = reinterpret_cast<std::weak_ptr<Context>*>(value)->lock();
455     if (ptr == nullptr) {
456         HILOG_WARN("invalid context.");
457         return nullptr;
458     }
459     NativeValue* object = CreateJsBaseContext(*engine, ptr, nullptr, nullptr, true);
460     auto systemModule = JsRuntime::LoadSystemModuleByEngine(engine, "application.Context", &object, 1);
461     if (systemModule == nullptr) {
462         HILOG_WARN("AttachBaseContext, invalid systemModule.");
463         return nullptr;
464     }
465     auto contextObj = systemModule->Get();
466     NativeObject *nObject = ConvertNativeValueTo<NativeObject>(contextObj);
467     if (nObject == nullptr) {
468         HILOG_WARN("AttachBaseContext, invalid nObject.");
469         return nullptr;
470     }
471     nObject->ConvertToNativeBindingObject(engine, DetachCallbackFunc, AttachBaseContext, value, nullptr);
472     auto workContext = new (std::nothrow) std::weak_ptr<Context>(ptr);
473     nObject->SetNativePointer(workContext,
474         [](NativeEngine *, void *data, void *) {
475             HILOG_DEBUG("Finalizer for weak_ptr base context is called");
476             delete static_cast<std::weak_ptr<Context> *>(data);
477         }, nullptr);
478     return contextObj;
479 }
480 
AttachApplicationContext(NativeEngine * engine,void * value,void * hint)481 NativeValue* AttachApplicationContext(NativeEngine* engine, void* value, void* hint)
482 {
483     HILOG_INFO("AttachApplicationContext");
484     if (value == nullptr || engine == nullptr) {
485         HILOG_WARN("invalid parameter.");
486         return nullptr;
487     }
488     auto ptr = reinterpret_cast<std::weak_ptr<ApplicationContext>*>(value)->lock();
489     if (ptr == nullptr) {
490         HILOG_WARN("invalid context.");
491         return nullptr;
492     }
493     NativeValue* object = JsApplicationContextUtils::CreateJsApplicationContext(*engine);
494     auto systemModule = JsRuntime::LoadSystemModuleByEngine(engine, "application.ApplicationContext", &object, 1);
495     if (systemModule == nullptr) {
496         HILOG_WARN("invalid systemModule.");
497         return nullptr;
498     }
499     auto contextObj = systemModule->Get();
500     NativeObject *nObject = ConvertNativeValueTo<NativeObject>(contextObj);
501     if (nObject == nullptr) {
502         HILOG_WARN("invalid nObject.");
503         return nullptr;
504     }
505     nObject->ConvertToNativeBindingObject(engine, DetachCallbackFunc, AttachApplicationContext, value, nullptr);
506     auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(ptr);
507     nObject->SetNativePointer(workContext,
508         [](NativeEngine *, void *data, void *) {
509             HILOG_DEBUG("Finalizer for weak_ptr application context is called");
510             delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
511         }, nullptr);
512     return contextObj;
513 }
514 
CreateJsBaseContext(NativeEngine & engine,std::shared_ptr<Context> context,DetachCallback detach,AttachCallback attach,bool keepContext)515 NativeValue* CreateJsBaseContext(NativeEngine& engine, std::shared_ptr<Context> context, DetachCallback detach,
516                                  AttachCallback attach, bool keepContext)
517 {
518     NativeValue* objValue;
519     if (detach == nullptr || attach == nullptr) {
520         objValue = engine.CreateObject();
521     } else {
522         objValue = engine.CreateNBObject(detach, attach);
523     }
524 
525     NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
526     if (object == nullptr) {
527         HILOG_WARN("invalid object.");
528         return objValue;
529     }
530     auto jsContext = std::make_unique<JsBaseContext>(context);
531     SetNamedNativePointer(engine, *object, BASE_CONTEXT_NAME, jsContext.release(), JsBaseContext::Finalizer);
532 
533     auto appInfo = context->GetApplicationInfo();
534     if (appInfo != nullptr) {
535         object->SetProperty("applicationInfo", CreateJsApplicationInfo(engine, *appInfo));
536     }
537     auto hapModuleInfo = context->GetHapModuleInfo();
538     if (hapModuleInfo != nullptr) {
539         object->SetProperty("currentHapModuleInfo", CreateJsHapModuleInfo(engine, *hapModuleInfo));
540     }
541     auto resourceManager = context->GetResourceManager();
542     if (resourceManager != nullptr) {
543         object->SetProperty("resourceManager", CreateJsResourceManager(engine, resourceManager, context));
544     }
545 
546     BindNativeProperty(*object, "cacheDir", JsBaseContext::GetCacheDir);
547     BindNativeProperty(*object, "tempDir", JsBaseContext::GetTempDir);
548     BindNativeProperty(*object, "filesDir", JsBaseContext::GetFilesDir);
549     BindNativeProperty(*object, "distributedFilesDir", JsBaseContext::GetDistributedFilesDir);
550     BindNativeProperty(*object, "databaseDir", JsBaseContext::GetDatabaseDir);
551     BindNativeProperty(*object, "preferencesDir", JsBaseContext::GetPreferencesDir);
552     BindNativeProperty(*object, "bundleCodeDir", JsBaseContext::GetBundleCodeDir);
553     BindNativeProperty(*object, "area", JsBaseContext::GetArea);
554     const char *moduleName = "JsBaseContext";
555     BindNativeFunction(engine, *object, "createBundleContext", moduleName, JsBaseContext::CreateBundleContext);
556     BindNativeFunction(engine, *object, "getApplicationContext", moduleName, JsBaseContext::GetApplicationContext);
557     BindNativeFunction(engine, *object, "switchArea", moduleName, JsBaseContext::SwitchArea);
558     BindNativeFunction(engine, *object, "getArea", moduleName, JsBaseContext::GetArea);
559     BindNativeFunction(engine, *object, "createModuleContext", moduleName, JsBaseContext::CreateModuleContext);
560 
561     return objValue;
562 }
563 }  // namespace AbilityRuntime
564 }  // namespace OHOS
565