• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <iostream>
19 #include "hilog_wrapper.h"
20 #include "js_application_context_utils.h"
21 #include "js_data_converter.h"
22 #include "js_runtime_utils.h"
23 
24 namespace OHOS {
25 namespace AbilityRuntime {
26 namespace {
27 constexpr char BASE_CONTEXT_NAME[] = "__base_context_ptr__";
28 
29 class JsBaseContext {
30 public:
JsBaseContext(std::weak_ptr<Context> && context)31     explicit JsBaseContext(std::weak_ptr<Context> &&context) : context_(std::move(context)) {}
32     virtual ~JsBaseContext() = default;
33 
34     static void Finalizer(NativeEngine *engine, void *data, void *hint);
35     static NativeValue *CreateBundleContext(NativeEngine *engine, NativeCallbackInfo *info);
36     static NativeValue *GetApplicationContext(NativeEngine *engine, NativeCallbackInfo *info);
37     static NativeValue *SwitchArea(NativeEngine *engine, NativeCallbackInfo *info);
38     static NativeValue *GetArea(NativeEngine *engine, NativeCallbackInfo *info);
39     static NativeValue *CreateModuleContext(NativeEngine *engine, NativeCallbackInfo *info);
40 
41     static NativeValue *GetCacheDir(NativeEngine *engine, NativeCallbackInfo *info);
42     static NativeValue *GetTempDir(NativeEngine *engine, NativeCallbackInfo *info);
43     static NativeValue *GetFilesDir(NativeEngine *engine, NativeCallbackInfo *info);
44     static NativeValue *GetDistributedFilesDir(NativeEngine *engine, NativeCallbackInfo *info);
45     static NativeValue *GetDatabaseDir(NativeEngine *engine, NativeCallbackInfo *info);
46     static NativeValue *GetPreferencesDir(NativeEngine *engine, NativeCallbackInfo *info);
47     static NativeValue *GetBundleCodeDir(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 *OnGetBundleCodeDir(NativeEngine &engine, NativeCallbackInfo &info);
56     NativeValue *OnSwitchArea(NativeEngine &engine, NativeCallbackInfo &info);
57     NativeValue *OnGetArea(NativeEngine &engine, NativeCallbackInfo &info);
58     NativeValue *OnGetApplicationContext(NativeEngine &engine, NativeCallbackInfo &info);
59 
60 protected:
61     std::weak_ptr<Context> context_;
62 };
63 
Finalizer(NativeEngine * engine,void * data,void * hint)64 void JsBaseContext::Finalizer(NativeEngine *engine, void *data, void *hint)
65 {
66     HILOG_DEBUG("called");
67     std::unique_ptr<JsBaseContext>(static_cast<JsBaseContext*>(data));
68 }
69 
CreateBundleContext(NativeEngine * engine,NativeCallbackInfo * info)70 NativeValue *JsBaseContext::CreateBundleContext(NativeEngine *engine, NativeCallbackInfo *info)
71 {
72     return nullptr;
73 }
74 
GetApplicationContext(NativeEngine * engine,NativeCallbackInfo * info)75 NativeValue *JsBaseContext::GetApplicationContext(NativeEngine *engine, NativeCallbackInfo *info)
76 {
77     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
78     return me != nullptr ? me->OnGetApplicationContext(*engine, *info) : nullptr;
79 }
80 
SwitchArea(NativeEngine * engine,NativeCallbackInfo * info)81 NativeValue *JsBaseContext::SwitchArea(NativeEngine *engine, NativeCallbackInfo *info)
82 {
83     HILOG_DEBUG("called");
84     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
85     return me != nullptr ? me->OnSwitchArea(*engine, *info) : nullptr;
86 }
87 
OnSwitchArea(NativeEngine & engine,NativeCallbackInfo & info)88 NativeValue *JsBaseContext::OnSwitchArea(NativeEngine &engine, NativeCallbackInfo &info)
89 {
90     if (info.argc == 0) {
91         HILOG_ERROR("Not enough params");
92         return engine.CreateUndefined();
93     }
94 
95     auto context = context_.lock();
96     if (!context) {
97         HILOG_WARN("context is already released");
98         return engine.CreateUndefined();
99     }
100 
101     int mode = 0;
102     if (!ConvertFromJsValue(engine, info.argv[0], mode)) {
103         HILOG_ERROR("Parse mode failed");
104         return engine.CreateUndefined();
105     }
106 
107     context->SwitchArea(mode);
108 
109     NativeValue *thisVar = info.thisVar;
110     NativeObject *object = ConvertNativeValueTo<NativeObject>(thisVar);
111     if (object == nullptr) {
112         HILOG_ERROR("object is nullptr");
113         return engine.CreateUndefined();
114     }
115     BindNativeProperty(*object, "cacheDir", GetCacheDir);
116     BindNativeProperty(*object, "tempDir", GetTempDir);
117     BindNativeProperty(*object, "filesDir", GetFilesDir);
118     BindNativeProperty(*object, "distributedFilesDir", GetDistributedFilesDir);
119     BindNativeProperty(*object, "databaseDir", GetDatabaseDir);
120     BindNativeProperty(*object, "preferencesDir", GetPreferencesDir);
121     BindNativeProperty(*object, "bundleCodeDir", GetBundleCodeDir);
122     return engine.CreateUndefined();
123 }
124 
CreateModuleContext(NativeEngine * engine,NativeCallbackInfo * info)125 NativeValue *JsBaseContext::CreateModuleContext(NativeEngine *engine, NativeCallbackInfo *info)
126 {
127     return nullptr;
128 }
129 
GetArea(NativeEngine * engine,NativeCallbackInfo * info)130 NativeValue *JsBaseContext::GetArea(NativeEngine *engine, NativeCallbackInfo *info)
131 {
132     HILOG_DEBUG("called");
133     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
134     return me != nullptr ? me->OnGetArea(*engine, *info) : nullptr;
135 }
136 
OnGetArea(NativeEngine & engine,NativeCallbackInfo & info)137 NativeValue *JsBaseContext::OnGetArea(NativeEngine &engine, NativeCallbackInfo &info)
138 {
139     auto context = context_.lock();
140     if (!context) {
141         HILOG_WARN("context is already released");
142         return engine.CreateUndefined();
143     }
144     int area = context->GetArea();
145     return engine.CreateNumber(area);
146 }
147 
GetCacheDir(NativeEngine * engine,NativeCallbackInfo * info)148 NativeValue *JsBaseContext::GetCacheDir(NativeEngine *engine, NativeCallbackInfo *info)
149 {
150     HILOG_DEBUG("called");
151     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
152     return me != nullptr ? me->OnGetCacheDir(*engine, *info) : nullptr;
153 }
154 
OnGetCacheDir(NativeEngine & engine,NativeCallbackInfo & info)155 NativeValue *JsBaseContext::OnGetCacheDir(NativeEngine &engine, NativeCallbackInfo &info)
156 {
157     auto context = context_.lock();
158     if (!context) {
159         HILOG_WARN("context is already released");
160         return engine.CreateUndefined();
161     }
162     std::string path = context->GetCacheDir();
163     return engine.CreateString(path.c_str(), path.length());
164 }
165 
GetTempDir(NativeEngine * engine,NativeCallbackInfo * info)166 NativeValue *JsBaseContext::GetTempDir(NativeEngine *engine, NativeCallbackInfo *info)
167 {
168     HILOG_DEBUG("called");
169     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
170     return me != nullptr ? me->OnGetTempDir(*engine, *info) : nullptr;
171 }
172 
OnGetTempDir(NativeEngine & engine,NativeCallbackInfo & info)173 NativeValue *JsBaseContext::OnGetTempDir(NativeEngine &engine, NativeCallbackInfo &info)
174 {
175     auto context = context_.lock();
176     if (!context) {
177         HILOG_WARN("context is already released");
178         return engine.CreateUndefined();
179     }
180     std::string path = context->GetTempDir();
181     return engine.CreateString(path.c_str(), path.length());
182 }
183 
GetFilesDir(NativeEngine * engine,NativeCallbackInfo * info)184 NativeValue *JsBaseContext::GetFilesDir(NativeEngine *engine, NativeCallbackInfo *info)
185 {
186     HILOG_DEBUG("called");
187     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
188     return me != nullptr ? me->OnGetFilesDir(*engine, *info) : nullptr;
189 }
190 
OnGetFilesDir(NativeEngine & engine,NativeCallbackInfo & info)191 NativeValue *JsBaseContext::OnGetFilesDir(NativeEngine &engine, NativeCallbackInfo &info)
192 {
193     auto context = context_.lock();
194     if (!context) {
195         HILOG_WARN("context is already released");
196         return engine.CreateUndefined();
197     }
198     std::string path = context->GetFilesDir();
199     return engine.CreateString(path.c_str(), path.length());
200 }
201 
GetDistributedFilesDir(NativeEngine * engine,NativeCallbackInfo * info)202 NativeValue *JsBaseContext::GetDistributedFilesDir(NativeEngine *engine, NativeCallbackInfo *info)
203 {
204     HILOG_DEBUG("called");
205     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
206     return me != nullptr ? me->OnGetDistributedFilesDir(*engine, *info) : nullptr;
207 }
208 
OnGetDistributedFilesDir(NativeEngine & engine,NativeCallbackInfo & info)209 NativeValue *JsBaseContext::OnGetDistributedFilesDir(NativeEngine &engine, NativeCallbackInfo &info)
210 {
211     auto context = context_.lock();
212     if (!context) {
213         HILOG_WARN("context is already released");
214         return engine.CreateUndefined();
215     }
216     std::string path = context->GetDistributedFilesDir();
217     return engine.CreateString(path.c_str(), path.length());
218 }
219 
GetDatabaseDir(NativeEngine * engine,NativeCallbackInfo * info)220 NativeValue *JsBaseContext::GetDatabaseDir(NativeEngine *engine, NativeCallbackInfo *info)
221 {
222     HILOG_DEBUG("called");
223     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
224     return me != nullptr ? me->OnGetDatabaseDir(*engine, *info) : nullptr;
225 }
226 
OnGetDatabaseDir(NativeEngine & engine,NativeCallbackInfo & info)227 NativeValue *JsBaseContext::OnGetDatabaseDir(NativeEngine &engine, NativeCallbackInfo &info)
228 {
229     auto context = context_.lock();
230     if (!context) {
231         HILOG_WARN("context is already released");
232         return engine.CreateUndefined();
233     }
234     std::string path = context->GetDatabaseDir();
235     return engine.CreateString(path.c_str(), path.length());
236 }
237 
GetPreferencesDir(NativeEngine * engine,NativeCallbackInfo * info)238 NativeValue *JsBaseContext::GetPreferencesDir(NativeEngine *engine, NativeCallbackInfo *info)
239 {
240     HILOG_DEBUG("called");
241     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
242     return me != nullptr ? me->OnGetPreferencesDir(*engine, *info) : nullptr;
243 }
244 
OnGetPreferencesDir(NativeEngine & engine,NativeCallbackInfo & info)245 NativeValue *JsBaseContext::OnGetPreferencesDir(NativeEngine &engine, NativeCallbackInfo &info)
246 {
247     auto context = context_.lock();
248     if (!context) {
249         HILOG_WARN("context is already released");
250         return engine.CreateUndefined();
251     }
252     std::string path = context->GetPreferencesDir();
253     return engine.CreateString(path.c_str(), path.length());
254 }
255 
GetBundleCodeDir(NativeEngine * engine,NativeCallbackInfo * info)256 NativeValue *JsBaseContext::GetBundleCodeDir(NativeEngine *engine, NativeCallbackInfo *info)
257 {
258     HILOG_DEBUG("called");
259     JsBaseContext *me = CheckParamsAndGetThis<JsBaseContext>(engine, info, BASE_CONTEXT_NAME);
260     return me != nullptr ? me->OnGetBundleCodeDir(*engine, *info) : nullptr;
261 }
262 
OnGetBundleCodeDir(NativeEngine & engine,NativeCallbackInfo & info)263 NativeValue *JsBaseContext::OnGetBundleCodeDir(NativeEngine &engine, NativeCallbackInfo &info)
264 {
265     auto context = context_.lock();
266     if (!context) {
267         HILOG_WARN("context is already released");
268         return engine.CreateUndefined();
269     }
270     std::string path = context->GetBundleCodeDir();
271     return engine.CreateString(path.c_str(), path.length());
272 }
273 
OnGetApplicationContext(NativeEngine & engine,NativeCallbackInfo & info)274 NativeValue *JsBaseContext::OnGetApplicationContext(NativeEngine &engine, NativeCallbackInfo &info)
275 {
276     HILOG_DEBUG("called");
277     NativeValue *value = JsApplicationContextUtils::CreateJsApplicationContext(engine, context_.lock());
278     auto systemModule = JsRuntime::LoadSystemModuleByEngine(&engine, "application.ApplicationContext", &value, 1);
279     if (systemModule == nullptr) {
280         return engine.CreateUndefined();
281     }
282     auto contextObj = systemModule->Get();
283     return contextObj;
284 }
285 } // namespace
286 
CreateJsBaseContext(NativeEngine & engine,std::shared_ptr<Context> context,bool keepContext)287 NativeValue *CreateJsBaseContext(NativeEngine &engine, std::shared_ptr<Context> context, bool keepContext)
288 {
289     NativeValue *objValue = engine.CreateObject();
290     NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
291     if (object == nullptr) {
292         HILOG_WARN("invalid object.");
293         return objValue;
294     }
295 
296     auto appInfo = context->GetApplicationInfo();
297     if (appInfo != nullptr) {
298         object->SetProperty("applicationInfo", CreateJsApplicationInfo(engine, *appInfo));
299     }
300     auto hapModuleInfo = context->GetHapModuleInfo();
301     if (hapModuleInfo != nullptr) {
302         object->SetProperty("currentHapModuleInfo", CreateJsHapModuleInfo(engine, *hapModuleInfo));
303     }
304 
305     auto jsContext = std::make_unique<JsBaseContext>(context);
306     SetNamedNativePointer(engine, *object, BASE_CONTEXT_NAME, jsContext.release(), JsBaseContext::Finalizer);
307 
308     BindNativeProperty(*object, "cacheDir", JsBaseContext::GetCacheDir);
309     BindNativeProperty(*object, "tempDir", JsBaseContext::GetTempDir);
310     BindNativeProperty(*object, "filesDir", JsBaseContext::GetFilesDir);
311     BindNativeProperty(*object, "distributedFilesDir", JsBaseContext::GetDistributedFilesDir);
312     BindNativeProperty(*object, "databaseDir", JsBaseContext::GetDatabaseDir);
313     BindNativeProperty(*object, "preferencesDir", JsBaseContext::GetPreferencesDir);
314     BindNativeProperty(*object, "bundleCodeDir", JsBaseContext::GetBundleCodeDir);
315     BindNativeProperty(*object, "area", JsBaseContext::GetArea);
316     const char *moduleName = "JsBaseContext";
317     BindNativeFunction(engine, *object, "createBundleContext", moduleName, JsBaseContext::CreateBundleContext);
318     BindNativeFunction(engine, *object, "getApplicationContext", moduleName, JsBaseContext::GetApplicationContext);
319     BindNativeFunction(engine, *object, "switchArea", moduleName, JsBaseContext::SwitchArea);
320     BindNativeFunction(engine, *object, "getArea", moduleName, JsBaseContext::GetArea);
321     BindNativeFunction(engine, *object, "createModuleContext", moduleName, JsBaseContext::CreateModuleContext);
322 
323     return objValue;
324 }
325 } // namespace AbilityRuntime
326 } // namespace OHOS
327