• 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(
263         env, object, DetachNewBaseContext, AttachBaseContext, workContext, nullptr);
264     napi_add_detached_finalizer(env, object, DetachFinalizeBaseContext, nullptr);
265     auto res = napi_wrap(env, object, workContext,
266         [](napi_env, void *data, void *) {
267             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr module context is called");
268             delete static_cast<std::weak_ptr<Context> *>(data);
269         },
270         nullptr, nullptr);
271     if (res != napi_ok && workContext != nullptr) {
272         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
273         delete workContext;
274         return CreateJsUndefined(env);
275     }
276     return object;
277 }
278 
CreateSystemHspModuleResourceManager(napi_env env,napi_callback_info info)279 napi_value JsBaseContext::CreateSystemHspModuleResourceManager(napi_env env, napi_callback_info info)
280 {
281     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext,
282         OnCreateSystemHspModuleResourceManager, BASE_CONTEXT_NAME);
283 }
284 
OnCreateSystemHspModuleResourceManager(napi_env env,NapiCallbackInfo & info)285 napi_value JsBaseContext::OnCreateSystemHspModuleResourceManager(napi_env env, NapiCallbackInfo& info)
286 {
287     auto context = context_.lock();
288     if (!context) {
289         TAG_LOGW(AAFwkTag::APPKIT, "null context");
290         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
291         return CreateJsUndefined(env);
292     }
293 
294     std::string bundleName = "";
295     if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
296         TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
297         ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
298         return CreateJsUndefined(env);
299     }
300     std::string moduleName = "";
301     if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
302         TAG_LOGE(AAFwkTag::APPKIT, "Parse moduleName failed");
303         ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
304         return CreateJsUndefined(env);
305     }
306 
307     std::shared_ptr<Global::Resource::ResourceManager> resourceManager = nullptr;
308     int32_t retCode = context->CreateSystemHspModuleResourceManager(bundleName, moduleName, resourceManager);
309     if (resourceManager == nullptr && retCode == ERR_ABILITY_RUNTIME_EXTERNAL_NOT_SYSTEM_HSP) {
310         TAG_LOGE(AAFwkTag::APPKIT, "null resourceManager");
311         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_NOT_SYSTEM_HSP);
312         return CreateJsUndefined(env);
313     }
314     if (resourceManager == nullptr) {
315         TAG_LOGE(AAFwkTag::APPKIT, "null resourceManager");
316         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
317         return CreateJsUndefined(env);
318     }
319 
320     return CreateJsResourceManager(env, resourceManager, nullptr);
321 }
322 
CreateModuleResourceManager(napi_env env,napi_callback_info info)323 napi_value JsBaseContext::CreateModuleResourceManager(napi_env env, napi_callback_info info)
324 {
325     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateModuleResourceManager, BASE_CONTEXT_NAME);
326 }
327 
OnCreateModuleResourceManager(napi_env env,NapiCallbackInfo & info)328 napi_value JsBaseContext::OnCreateModuleResourceManager(napi_env env, NapiCallbackInfo& info)
329 {
330     auto context = context_.lock();
331     if (!context) {
332         TAG_LOGW(AAFwkTag::APPKIT, "null context");
333         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
334         return CreateJsUndefined(env);
335     }
336 
337     std::string bundleName;
338     if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
339         TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
340         ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
341         return CreateJsUndefined(env);
342     }
343     std::string moduleName;
344     if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
345         TAG_LOGE(AAFwkTag::APPKIT, "Parse moduleName failed");
346         ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
347         return CreateJsUndefined(env);
348     }
349     if (!CheckCallerIsSystemApp()) {
350         TAG_LOGE(AAFwkTag::APPKIT, "not system-app");
351         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
352         return CreateJsUndefined(env);
353     }
354     auto resourceManager = context->CreateModuleResourceManager(bundleName, moduleName);
355     if (resourceManager == nullptr) {
356         TAG_LOGE(AAFwkTag::APPKIT, "null resourceManager");
357         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
358         return CreateJsUndefined(env);
359     }
360     auto jsResourceManager = CreateJsResourceManager(env, resourceManager, nullptr);
361     return jsResourceManager;
362 }
363 
GetArea(napi_env env,napi_callback_info info)364 napi_value JsBaseContext::GetArea(napi_env env, napi_callback_info info)
365 {
366     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetArea, BASE_CONTEXT_NAME);
367 }
368 
OnGetArea(napi_env env,NapiCallbackInfo & info)369 napi_value JsBaseContext::OnGetArea(napi_env env, NapiCallbackInfo& info)
370 {
371     auto context = context_.lock();
372     if (!context) {
373         TAG_LOGW(AAFwkTag::APPKIT, "null context");
374         return CreateJsUndefined(env);
375     }
376     int area = context->GetArea();
377     return CreateJsValue(env, area);
378 }
379 
GetCacheDir(napi_env env,napi_callback_info info)380 napi_value JsBaseContext::GetCacheDir(napi_env env, napi_callback_info info)
381 {
382     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetCacheDir, BASE_CONTEXT_NAME);
383 }
384 
OnGetCacheDir(napi_env env,NapiCallbackInfo & info)385 napi_value JsBaseContext::OnGetCacheDir(napi_env env, NapiCallbackInfo& info)
386 {
387     auto context = context_.lock();
388     if (!context) {
389         TAG_LOGW(AAFwkTag::APPKIT, "null context");
390         return CreateJsUndefined(env);
391     }
392     std::string path = context->GetCacheDir();
393     return CreateJsValue(env, path);
394 }
395 
GetTempDir(napi_env env,napi_callback_info info)396 napi_value JsBaseContext::GetTempDir(napi_env env, napi_callback_info info)
397 {
398     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetTempDir, BASE_CONTEXT_NAME);
399 }
400 
OnGetTempDir(napi_env env,NapiCallbackInfo & info)401 napi_value JsBaseContext::OnGetTempDir(napi_env env, NapiCallbackInfo& info)
402 {
403     auto context = context_.lock();
404     if (!context) {
405         TAG_LOGW(AAFwkTag::APPKIT, "null context");
406         return CreateJsUndefined(env);
407     }
408     std::string path = context->GetTempDir();
409     return CreateJsValue(env, path);
410 }
411 
GetResourceDir(napi_env env,napi_callback_info info)412 napi_value JsBaseContext::GetResourceDir(napi_env env, napi_callback_info info)
413 {
414     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetResourceDir, BASE_CONTEXT_NAME);
415 }
416 
OnGetResourceDir(napi_env env,NapiCallbackInfo & info)417 napi_value JsBaseContext::OnGetResourceDir(napi_env env, NapiCallbackInfo& info)
418 {
419     auto context = context_.lock();
420     if (!context) {
421         TAG_LOGW(AAFwkTag::APPKIT, "null context");
422         return CreateJsUndefined(env);
423     }
424     std::string path = context->GetResourceDir();
425     return CreateJsValue(env, path);
426 }
427 
GetFilesDir(napi_env env,napi_callback_info info)428 napi_value JsBaseContext::GetFilesDir(napi_env env, napi_callback_info info)
429 {
430     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetFilesDir, BASE_CONTEXT_NAME);
431 }
432 
OnGetFilesDir(napi_env env,NapiCallbackInfo & info)433 napi_value JsBaseContext::OnGetFilesDir(napi_env env, NapiCallbackInfo& info)
434 {
435     auto context = context_.lock();
436     if (!context) {
437         TAG_LOGW(AAFwkTag::APPKIT, "null context");
438         return CreateJsUndefined(env);
439     }
440     std::string path = context->GetFilesDir();
441     return CreateJsValue(env, path);
442 }
443 
GetDistributedFilesDir(napi_env env,napi_callback_info info)444 napi_value JsBaseContext::GetDistributedFilesDir(napi_env env, napi_callback_info info)
445 {
446     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetDistributedFilesDir, BASE_CONTEXT_NAME);
447 }
448 
OnGetDistributedFilesDir(napi_env env,NapiCallbackInfo & info)449 napi_value JsBaseContext::OnGetDistributedFilesDir(napi_env env, NapiCallbackInfo& info)
450 {
451     auto context = context_.lock();
452     if (!context) {
453         TAG_LOGW(AAFwkTag::APPKIT, "null context");
454         return CreateJsUndefined(env);
455     }
456     std::string path = context->GetDistributedFilesDir();
457     return CreateJsValue(env, path);
458 }
459 
GetDatabaseDir(napi_env env,napi_callback_info info)460 napi_value JsBaseContext::GetDatabaseDir(napi_env env, napi_callback_info info)
461 {
462     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetDatabaseDir, BASE_CONTEXT_NAME);
463 }
464 
OnGetDatabaseDir(napi_env env,NapiCallbackInfo & info)465 napi_value JsBaseContext::OnGetDatabaseDir(napi_env env, NapiCallbackInfo& info)
466 {
467     auto context = context_.lock();
468     if (!context) {
469         TAG_LOGW(AAFwkTag::APPKIT, "null context");
470         return CreateJsUndefined(env);
471     }
472     std::string path = context->GetDatabaseDir();
473     return CreateJsValue(env, path);
474 }
475 
GetPreferencesDir(napi_env env,napi_callback_info info)476 napi_value JsBaseContext::GetPreferencesDir(napi_env env, napi_callback_info info)
477 {
478     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetPreferencesDir, BASE_CONTEXT_NAME);
479 }
480 
OnGetPreferencesDir(napi_env env,NapiCallbackInfo & info)481 napi_value JsBaseContext::OnGetPreferencesDir(napi_env env, NapiCallbackInfo& info)
482 {
483     auto context = context_.lock();
484     if (!context) {
485         TAG_LOGW(AAFwkTag::APPKIT, "null context");
486         return CreateJsUndefined(env);
487     }
488     std::string path = context->GetPreferencesDir();
489     return CreateJsValue(env, path);
490 }
491 
GetGroupDir(napi_env env,napi_callback_info info)492 napi_value JsBaseContext::GetGroupDir(napi_env env, napi_callback_info info)
493 {
494     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetGroupDir, BASE_CONTEXT_NAME);
495 }
496 
OnGetGroupDir(napi_env env,NapiCallbackInfo & info)497 napi_value JsBaseContext::OnGetGroupDir(napi_env env, NapiCallbackInfo& info)
498 {
499     if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
500         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
501         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
502         return CreateJsUndefined(env);
503     }
504 
505     std::string groupId;
506     if (!ConvertFromJsValue(env, info.argv[0], groupId)) {
507         TAG_LOGE(AAFwkTag::APPKIT, "Parse groupId failed");
508         ThrowInvalidParamError(env, "Parse param groupId failed, groupId must be string.");
509         return CreateJsUndefined(env);
510     }
511     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
512     auto path = std::make_shared<std::string>();
513     NapiAsyncTask::ExecuteCallback execute = [context = context_, groupId, path, innerErrCode]() {
514         auto completeContext = context.lock();
515         if (!completeContext) {
516             *innerErrCode = ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST;
517             return;
518         }
519         *path = completeContext->GetGroupDir(groupId);
520     };
521     auto complete = [innerErrCode, path]
522         (napi_env env, NapiAsyncTask& task, int32_t status) {
523         if (*innerErrCode == ERR_OK) {
524             task.ResolveWithNoError(env, CreateJsValue(env, *path));
525         } else {
526             task.Reject(env, CreateJsError(env, *innerErrCode, "completeContext if already released."));
527         }
528     };
529 
530     napi_value lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
531     napi_value result = nullptr;
532     NapiAsyncTask::ScheduleHighQos("JsBaseContext::OnGetGroupDir",
533         env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
534     return result;
535 }
536 
GetBundleCodeDir(napi_env env,napi_callback_info info)537 napi_value JsBaseContext::GetBundleCodeDir(napi_env env, napi_callback_info info)
538 {
539     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetBundleCodeDir, BASE_CONTEXT_NAME);
540 }
541 
OnGetBundleCodeDir(napi_env env,NapiCallbackInfo & info)542 napi_value JsBaseContext::OnGetBundleCodeDir(napi_env env, NapiCallbackInfo& info)
543 {
544     auto context = context_.lock();
545     if (!context) {
546         TAG_LOGW(AAFwkTag::APPKIT, "null context");
547         return CreateJsUndefined(env);
548     }
549     std::string path = context->GetBundleCodeDir();
550     return CreateJsValue(env, path);
551 }
552 
GetCloudFileDir(napi_env env,napi_callback_info info)553 napi_value JsBaseContext::GetCloudFileDir(napi_env env, napi_callback_info info)
554 {
555     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetCloudFileDir, BASE_CONTEXT_NAME);
556 }
557 
OnGetCloudFileDir(napi_env env,NapiCallbackInfo & info)558 napi_value JsBaseContext::OnGetCloudFileDir(napi_env env, NapiCallbackInfo& info)
559 {
560     auto context = context_.lock();
561     if (!context) {
562         TAG_LOGW(AAFwkTag::APPKIT, "null context");
563         return CreateJsUndefined(env);
564     }
565     std::string path = context->GetCloudFileDir();
566     return CreateJsValue(env, path);
567 }
568 
GetProcessName(napi_env env,napi_callback_info info)569 napi_value JsBaseContext::GetProcessName(napi_env env, napi_callback_info info)
570 {
571     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnGetProcessName, BASE_CONTEXT_NAME);
572 }
573 
OnGetProcessName(napi_env env,NapiCallbackInfo & info)574 napi_value JsBaseContext::OnGetProcessName(napi_env env, NapiCallbackInfo &info)
575 {
576     auto context = context_.lock();
577     if (context == nullptr) {
578         TAG_LOGE(AAFwkTag::APPKIT, "context is already released");
579         return CreateJsUndefined(env);
580     }
581     std::string name = context->GetProcessName();
582     return CreateJsValue(env, name);
583 }
584 
OnCreateBundleContext(napi_env env,NapiCallbackInfo & info)585 napi_value JsBaseContext::OnCreateBundleContext(napi_env env, NapiCallbackInfo& info)
586 {
587     if (!CheckCallerIsSystemApp()) {
588         TAG_LOGE(AAFwkTag::APPKIT, "not system-app");
589         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
590         return CreateJsUndefined(env);
591     }
592 
593     if (info.argc == 0) {
594         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
595         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
596         return CreateJsUndefined(env);
597     }
598 
599     auto context = context_.lock();
600     if (!context) {
601         TAG_LOGW(AAFwkTag::APPKIT, "null context");
602         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
603         return CreateJsUndefined(env);
604     }
605 
606     std::string bundleName;
607     if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
608         TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
609         ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
610         return CreateJsUndefined(env);
611     }
612 
613     auto bundleContext = context->CreateBundleContext(bundleName);
614     if (!bundleContext) {
615         TAG_LOGE(AAFwkTag::APPKIT, "null bundleContext");
616         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
617         return CreateJsUndefined(env);
618     }
619     return CreateJsBundleContext(env, bundleContext);
620 }
621 
CreateJsBundleContext(napi_env env,const std::shared_ptr<Context> & bundleContext)622 napi_value JsBaseContext::CreateJsBundleContext(napi_env env, const std::shared_ptr<Context>& bundleContext)
623 {
624     napi_value value = CreateJsBaseContext(env, bundleContext, true);
625     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
626     if (systemModule == nullptr) {
627         TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
628         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
629         return CreateJsUndefined(env);
630     }
631     napi_value object = systemModule->GetNapiValue();
632     if (!CheckTypeForNapiValue(env, object, napi_object)) {
633         TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
634         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
635         return CreateJsUndefined(env);
636     }
637     auto workContext = new (std::nothrow) std::weak_ptr<Context>(bundleContext);
638     napi_coerce_to_native_binding_object(
639         env, object, DetachNewBaseContext, AttachBaseContext, workContext, nullptr);
640     napi_add_detached_finalizer(env, object, DetachFinalizeBaseContext, nullptr);
641     auto res = napi_wrap(env, object, workContext,
642         [](napi_env, void *data, void *) {
643             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr bundle context is called");
644             delete static_cast<std::weak_ptr<Context> *>(data);
645         },
646         nullptr, nullptr);
647     if (res != napi_ok && workContext != nullptr) {
648         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
649         delete workContext;
650         return CreateJsUndefined(env);
651     }
652     return object;
653 }
654 
OnGetApplicationContext(napi_env env,NapiCallbackInfo & info)655 napi_value JsBaseContext::OnGetApplicationContext(napi_env env, NapiCallbackInfo& info)
656 {
657     auto context = context_.lock();
658     if (!context) {
659         TAG_LOGW(AAFwkTag::APPKIT, "null context");
660         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
661         return CreateJsUndefined(env);
662     }
663 
664     auto applicationContext = Context::GetApplicationContext();
665     if (applicationContext == nullptr) {
666         TAG_LOGW(AAFwkTag::APPKIT, "null applicationContext");
667         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
668         return CreateJsUndefined(env);
669     }
670 
671     if (!applicationContext->GetApplicationInfoUpdateFlag()) {
672         std::shared_ptr<NativeReference> applicationContextObj =
673             ApplicationContextManager::GetApplicationContextManager().GetGlobalObject(env);
674         if (applicationContextObj != nullptr) {
675             napi_value objValue = applicationContextObj->GetNapiValue();
676             return objValue;
677         }
678     }
679     return CreateJSApplicationContext(env, applicationContext);
680 }
681 
CreateAreaModeContext(napi_env env,napi_callback_info info)682 napi_value JsBaseContext::CreateAreaModeContext(napi_env env, napi_callback_info info)
683 {
684     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateAreaModeContext, BASE_CONTEXT_NAME);
685 }
686 
OnCreateAreaModeContext(napi_env env,NapiCallbackInfo & info)687 napi_value JsBaseContext::OnCreateAreaModeContext(napi_env env, NapiCallbackInfo &info)
688 {
689     if (info.argc == 0) {
690         TAG_LOGE(AAFwkTag::APPKIT, "not enough params");
691         ThrowTooFewParametersError(env);
692         return CreateJsUndefined(env);
693     }
694 
695     auto context = context_.lock();
696     if (context == nullptr) {
697         TAG_LOGE(AAFwkTag::APPKIT, "context is already released");
698         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
699         return CreateJsUndefined(env);
700     }
701 
702     int areaMode = 0;
703     if (!ConvertFromJsValue(env, info.argv[0], areaMode)) {
704         TAG_LOGE(AAFwkTag::APPKIT, "parse areaMode failed");
705         ThrowInvalidParamError(env, "parse param areaMode failed, areaMode must be number.");
706         return CreateJsUndefined(env);
707     }
708     auto areaContext = context->CreateAreaModeContext(areaMode);
709     if (areaContext == nullptr) {
710         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
711         TAG_LOGE(AAFwkTag::APPKIT, "failed to create areaContext");
712         return CreateJsUndefined(env);
713     }
714 
715     return CreateJsContext(env, areaContext);
716 }
717 
CreateDisplayContext(napi_env env,napi_callback_info info)718 napi_value JsBaseContext::CreateDisplayContext(napi_env env, napi_callback_info info)
719 {
720     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsBaseContext, OnCreateDisplayContext, BASE_CONTEXT_NAME);
721 }
722 
OnCreateDisplayContext(napi_env env,NapiCallbackInfo & info)723 napi_value JsBaseContext::OnCreateDisplayContext(napi_env env, NapiCallbackInfo &info)
724 {
725 #ifdef SUPPORT_GRAPHICS
726     if (info.argc == 0) {
727         TAG_LOGE(AAFwkTag::APPKIT, "not enough params");
728         ThrowTooFewParametersError(env);
729         return CreateJsUndefined(env);
730     }
731 
732     auto context = context_.lock();
733     if (context == nullptr) {
734         TAG_LOGE(AAFwkTag::APPKIT, "context is already released");
735         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
736         return CreateJsUndefined(env);
737     }
738 
739     int64_t displayId = -1;
740     if (!ConvertFromJsValue(env, info.argv[0], displayId)) {
741         TAG_LOGE(AAFwkTag::APPKIT, "parse displayId failed");
742         ThrowInvalidParamError(env, "parse param displayId failed, displayId must be number.");
743         return CreateJsUndefined(env);
744     }
745     if (displayId < 0) {
746         TAG_LOGE(AAFwkTag::APPKIT, "displayId is invalid, less than 0");
747         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
748         return CreateJsUndefined(env);
749     }
750     uint64_t validDisplayId = static_cast<uint64_t>(displayId);
751 
752     auto displayContext = context->CreateDisplayContext(validDisplayId);
753     if (displayContext == nullptr) {
754         TAG_LOGE(AAFwkTag::APPKIT, "failed to create displayContext");
755         return CreateJsUndefined(env);
756     }
757     return CreateJsContext(env, displayContext);
758 #else
759     return CreateJsUndefined(env);
760 #endif
761 }
762 
CreateJsContext(napi_env env,const std::shared_ptr<Context> & context)763 napi_value JsBaseContext::CreateJsContext(napi_env env, const std::shared_ptr<Context> &context)
764 {
765     napi_value value = CreateJsBaseContext(env, context, true);
766     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
767     if (systemModule == nullptr) {
768         TAG_LOGE(AAFwkTag::APPKIT, "invalid systemModule");
769         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
770         return CreateJsUndefined(env);
771     }
772     napi_value object = systemModule->GetNapiValue();
773     if (!CheckTypeForNapiValue(env, object, napi_object)) {
774         TAG_LOGE(AAFwkTag::APPKIT, "failed to get object");
775         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
776         return CreateJsUndefined(env);
777     }
778     auto workContext = new (std::nothrow) std::weak_ptr<Context>(context);
779     auto status = napi_coerce_to_native_binding_object(
780         env, object, DetachNewBaseContext, AttachBaseContext, workContext, nullptr);
781     napi_add_detached_finalizer(env, object, DetachFinalizeBaseContext, nullptr);
782     if (status != napi_ok) {
783         TAG_LOGE(AAFwkTag::APPKIT, "coerce context failed: %{public}d", status);
784         delete workContext;
785         return CreateJsUndefined(env);
786     }
787     auto res = napi_wrap(env, object, workContext,
788         [](napi_env, void *data, void *) {
789             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr module context is called");
790             delete static_cast<std::weak_ptr<Context> *>(data);
791         },
792         nullptr, nullptr);
793     if (res != napi_ok && workContext != nullptr) {
794         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
795         delete workContext;
796         return CreateJsUndefined(env);
797     }
798     return object;
799 }
800 
CreateJSApplicationContext(napi_env env,const std::shared_ptr<ApplicationContext> applicationContext)801 napi_value JsBaseContext::CreateJSApplicationContext(napi_env env,
802     const std::shared_ptr<ApplicationContext> applicationContext)
803 {
804     napi_value value = JsApplicationContextUtils::CreateJsApplicationContext(env);
805     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.ApplicationContext", &value, 1);
806     if (systemModule == nullptr) {
807         TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
808         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
809         return CreateJsUndefined(env);
810     }
811     napi_value object = systemModule->GetNapiValue();
812     if (!CheckTypeForNapiValue(env, object, napi_object)) {
813         TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
814         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
815         return CreateJsUndefined(env);
816     }
817     auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(applicationContext);
818     napi_coerce_to_native_binding_object(
819         env, object, DetachNewApplicationContext, AttachApplicationContext, workContext, nullptr);
820     napi_add_detached_finalizer(env, object, DetachFinalizeApplicationContext, nullptr);
821     auto res = napi_wrap(env, object, workContext,
822         [](napi_env, void *data, void *) {
823             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr application context is called");
824             delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
825             data = nullptr;
826         },
827         nullptr, nullptr);
828     if (res != napi_ok && workContext != nullptr) {
829         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
830         delete workContext;
831         return CreateJsUndefined(env);
832     }
833     napi_ref ref = nullptr;
834     napi_create_reference(env, object, 1, &ref);
835     ApplicationContextManager::GetApplicationContextManager()
836         .AddGlobalObject(env, std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(ref)));
837     applicationContext->SetApplicationInfoUpdateFlag(false);
838     return object;
839 }
840 
CheckCallerIsSystemApp()841 bool JsBaseContext::CheckCallerIsSystemApp()
842 {
843     auto selfToken = IPCSkeleton::GetSelfTokenID();
844     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
845         return false;
846     }
847     return true;
848 }
849 } // namespace
850 
AttachBaseContext(napi_env env,void * value,void * hint)851 napi_value AttachBaseContext(napi_env env, void* value, void* hint)
852 {
853     TAG_LOGD(AAFwkTag::APPKIT, "called");
854     if (value == nullptr || env == nullptr) {
855         TAG_LOGW(AAFwkTag::APPKIT, "invalid parameter");
856         return nullptr;
857     }
858     auto ptr = reinterpret_cast<std::weak_ptr<Context>*>(value)->lock();
859     if (ptr == nullptr) {
860         TAG_LOGW(AAFwkTag::APPKIT, "null ptr");
861         return nullptr;
862     }
863     napi_value object = CreateJsBaseContext(env, ptr, true);
864     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &object, 1);
865     if (systemModule == nullptr) {
866         TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
867         return nullptr;
868     }
869 
870     napi_value contextObj = systemModule->GetNapiValue();
871     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
872         TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
873         return nullptr;
874     }
875     auto workContext = new (std::nothrow) std::weak_ptr<Context>(ptr);
876     napi_coerce_to_native_binding_object(
877         env, contextObj, DetachNewBaseContext, AttachBaseContext, workContext, nullptr);
878     napi_add_detached_finalizer(env, contextObj, DetachFinalizeBaseContext, nullptr);
879     auto res = napi_wrap(env, contextObj, workContext,
880         [](napi_env, void *data, void *) {
881             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr base context is called");
882             delete static_cast<std::weak_ptr<Context> *>(data);
883         },
884         nullptr, nullptr);
885     if (res != napi_ok && workContext != nullptr) {
886         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
887         delete workContext;
888         return nullptr;
889     }
890     return contextObj;
891 }
892 
AttachApplicationContext(napi_env env,void * value,void * hint)893 napi_value AttachApplicationContext(napi_env env, void* value, void* hint)
894 {
895     TAG_LOGD(AAFwkTag::APPKIT, "called");
896     if (value == nullptr || env == nullptr) {
897         TAG_LOGW(AAFwkTag::APPKIT, "invalid parameter");
898         return nullptr;
899     }
900     auto ptr = reinterpret_cast<std::weak_ptr<ApplicationContext>*>(value)->lock();
901     if (ptr == nullptr) {
902         TAG_LOGW(AAFwkTag::APPKIT, "null ptr");
903         return nullptr;
904     }
905     napi_value object = JsApplicationContextUtils::CreateJsApplicationContext(env);
906     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.ApplicationContext", &object, 1);
907     if (systemModule == nullptr) {
908         TAG_LOGW(AAFwkTag::APPKIT, "null systemModule");
909         return nullptr;
910     }
911     auto contextObj = systemModule->GetNapiValue();
912     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
913         TAG_LOGE(AAFwkTag::APPKIT, "get object failed");
914         return nullptr;
915     }
916     auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(ptr);
917     napi_coerce_to_native_binding_object(
918         env, contextObj, DetachNewApplicationContext, AttachApplicationContext, workContext, nullptr);
919     napi_add_detached_finalizer(env, contextObj, DetachFinalizeApplicationContext, nullptr);
920     auto res = napi_wrap(env, contextObj, workContext,
921         [](napi_env, void *data, void *) {
922             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr application context is called");
923             delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
924             data = nullptr;
925         },
926         nullptr, nullptr);
927     if (res != napi_ok && workContext != nullptr) {
928         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
929         delete workContext;
930         return nullptr;
931     }
932     return contextObj;
933 }
934 
BindPropertyAndFunction(napi_env env,napi_value object,const char * moduleName)935 void BindPropertyAndFunction(napi_env env, napi_value object, const char* moduleName)
936 {
937     BindNativeProperty(env, object, "cacheDir", JsBaseContext::GetCacheDir);
938     BindNativeProperty(env, object, "tempDir", JsBaseContext::GetTempDir);
939     BindNativeProperty(env, object, "resourceDir", JsBaseContext::GetResourceDir);
940     BindNativeProperty(env, object, "filesDir", JsBaseContext::GetFilesDir);
941     BindNativeProperty(env, object, "distributedFilesDir", JsBaseContext::GetDistributedFilesDir);
942     BindNativeProperty(env, object, "databaseDir", JsBaseContext::GetDatabaseDir);
943     BindNativeProperty(env, object, "preferencesDir", JsBaseContext::GetPreferencesDir);
944     BindNativeProperty(env, object, "bundleCodeDir", JsBaseContext::GetBundleCodeDir);
945     BindNativeProperty(env, object, "cloudFileDir", JsBaseContext::GetCloudFileDir);
946     BindNativeProperty(env, object, "area", JsBaseContext::GetArea);
947     BindNativeProperty(env, object, "processName", JsBaseContext::GetProcessName);
948 
949     BindNativeFunction(env, object, "createBundleContext", moduleName, JsBaseContext::CreateBundleContext);
950     BindNativeFunction(env, object, "getApplicationContext", moduleName, JsBaseContext::GetApplicationContext);
951     BindNativeFunction(env, object, "switchArea", moduleName, JsBaseContext::SwitchArea);
952     BindNativeFunction(env, object, "getArea", moduleName, JsBaseContext::GetArea);
953     BindNativeFunction(env, object, "createModuleContext", moduleName, JsBaseContext::CreateModuleContext);
954     BindNativeFunction(env, object, "createSystemHspModuleResourceManager", moduleName,
955         JsBaseContext::CreateSystemHspModuleResourceManager);
956     BindNativeFunction(env, object, "createModuleResourceManager", moduleName,
957         JsBaseContext::CreateModuleResourceManager);
958     BindNativeFunction(env, object, "getGroupDir", moduleName, JsBaseContext::GetGroupDir);
959     BindNativeFunction(env, object, "createAreaModeContext", moduleName, JsBaseContext::CreateAreaModeContext);
960     BindNativeFunction(env, object, "createDisplayContext", moduleName, JsBaseContext::CreateDisplayContext);
961 }
CreateJsBaseContext(napi_env env,std::shared_ptr<Context> context,bool keepContext)962 napi_value CreateJsBaseContext(napi_env env, std::shared_ptr<Context> context, bool keepContext)
963 {
964     napi_value object = nullptr;
965     napi_create_object(env, &object);
966     if (object == nullptr) {
967         TAG_LOGW(AAFwkTag::APPKIT, "null object");
968         return nullptr;
969     }
970     if (context == nullptr) {
971         TAG_LOGE(AAFwkTag::APPKIT, "null context");
972         return nullptr;
973     }
974     auto jsContext = std::make_unique<JsBaseContext>(context);
975     SetNamedNativePointer(env, object, BASE_CONTEXT_NAME, jsContext.release(), JsBaseContext::Finalizer);
976 
977     auto appInfo = context->GetApplicationInfo();
978     if (appInfo != nullptr) {
979         napi_set_named_property(env, object, "applicationInfo", CreateJsApplicationInfo(env, *appInfo));
980     }
981     auto hapModuleInfo = context->GetHapModuleInfo();
982     if (hapModuleInfo != nullptr) {
983         napi_set_named_property(env, object, "currentHapModuleInfo", CreateJsHapModuleInfo(env, *hapModuleInfo));
984     }
985     auto resourceManager = context->GetResourceManager();
986     if (resourceManager != nullptr) {
987         auto jsResourceManager = CreateJsResourceManager(env, resourceManager, context);
988         if (jsResourceManager != nullptr) {
989             napi_set_named_property(env, object, "resourceManager", jsResourceManager);
990         } else {
991             TAG_LOGE(AAFwkTag::APPKIT, "null jsResourceManager");
992         }
993     }
994     napi_value contextValue = nullptr;
995     Context *contextPtr = context.get();
996     int64_t contextAddress = reinterpret_cast<int64_t>(contextPtr);
997     auto status = napi_create_int64(env, contextAddress, &contextValue);
998     if (status != napi_ok) {
999         TAG_LOGE(AAFwkTag::APPKIT, "get context index fial");
1000         return nullptr;
1001     }
1002     napi_set_named_property(env, object, "index", contextValue);
1003 
1004     std::string type = "Context";
1005     napi_set_named_property(env, object, "contextType", CreateJsValue(env, type));
1006 
1007     const char *moduleName = "JsBaseContext";
1008     BindPropertyAndFunction(env, object, moduleName);
1009     return object;
1010 }
1011 }  // namespace AbilityRuntime
1012 }  // namespace OHOS
1013