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