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