• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_context_utils.h"
17 
18 #include "ability_runtime_error_util.h"
19 #include "hilog_wrapper.h"
20 #include "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