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