1 /*
2  * Copyright (c) 2023-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_application_context_utils.h"
17 
18 #include <map>
19 #include "hilog_tag_wrapper.h"
20 #include "js_context_utils.h"
21 #include "js_data_converter.h"
22 #include "js_runtime_utils.h"
23 #include "js_runtime.h"
24 
25 namespace OHOS {
26 namespace AbilityRuntime {
27 namespace {
28 constexpr char APPLICATION_CONTEXT_NAME[] = "__application_context_ptr__";
29 const char *MD_NAME = "JsApplicationContextUtils";
30 } // namespace
31 
CreateBundleContext(napi_env env,napi_callback_info info)32 napi_value JsApplicationContextUtils::CreateBundleContext(napi_env env, napi_callback_info info)
33 {
34     return nullptr;
35 }
36 
SetColorMode(napi_env env,napi_callback_info info)37 napi_value JsApplicationContextUtils::SetColorMode(napi_env env, napi_callback_info info)
38 {
39     return nullptr;
40 }
41 
SwitchArea(napi_env env,napi_callback_info info)42 napi_value JsApplicationContextUtils::SwitchArea(napi_env env, napi_callback_info info)
43 {
44     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnSwitchArea, APPLICATION_CONTEXT_NAME);
45 }
46 
OnSwitchArea(napi_env env,NapiCallbackInfo & info)47 napi_value JsApplicationContextUtils::OnSwitchArea(napi_env env, NapiCallbackInfo &info)
48 {
49     napi_value object = info.thisVar;
50     if (object == nullptr) {
51         TAG_LOGE(AAFwkTag::ABILITY_SIM, "null object");
52         return CreateJsUndefined(env);
53     }
54     BindNativeProperty(env, object, "cacheDir", GetCacheDir);
55     BindNativeProperty(env, object, "tempDir", GetTempDir);
56     BindNativeProperty(env, object, "resourceDir", GetResourceDir);
57     BindNativeProperty(env, object, "filesDir", GetFilesDir);
58     BindNativeProperty(env, object, "distributedFilesDir", GetDistributedFilesDir);
59     BindNativeProperty(env, object, "databaseDir", GetDatabaseDir);
60     BindNativeProperty(env, object, "preferencesDir", GetPreferencesDir);
61     BindNativeProperty(env, object, "bundleCodeDir", GetBundleCodeDir);
62     BindNativeProperty(env, object, "cloudFileDir", GetCloudFileDir);
63     return CreateJsUndefined(env);
64 }
65 
66 
CreateModuleContext(napi_env env,napi_callback_info info)67 napi_value JsApplicationContextUtils::CreateModuleContext(napi_env env, napi_callback_info info)
68 {
69     return nullptr;
70 }
71 
CreateModuleResourceManager(napi_env env,napi_callback_info info)72 napi_value JsApplicationContextUtils::CreateModuleResourceManager(napi_env env, napi_callback_info info)
73 {
74     return nullptr;
75 }
76 
GetTempDir(napi_env env,napi_callback_info info)77 napi_value JsApplicationContextUtils::GetTempDir(napi_env env, napi_callback_info info)
78 {
79     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetTempDir, APPLICATION_CONTEXT_NAME);
80 }
81 
OnGetTempDir(napi_env env,NapiCallbackInfo & info)82 napi_value JsApplicationContextUtils::OnGetTempDir(napi_env env, NapiCallbackInfo &info)
83 {
84     auto context = context_.lock();
85     if (!context) {
86         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
87         return CreateJsUndefined(env);
88     }
89     std::string path = context->GetTempDir();
90     return CreateJsValue(env, path);
91 }
92 
GetResourceDir(napi_env env,napi_callback_info info)93 napi_value JsApplicationContextUtils::GetResourceDir(napi_env env, napi_callback_info info)
94 {
95     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetResourceDir, APPLICATION_CONTEXT_NAME);
96 }
97 
OnGetResourceDir(napi_env env,NapiCallbackInfo & info)98 napi_value JsApplicationContextUtils::OnGetResourceDir(napi_env env, NapiCallbackInfo &info)
99 {
100     auto context = context_.lock();
101     if (!context) {
102         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
103         return CreateJsUndefined(env);
104     }
105     std::string path = context->GetResourceDir();
106     return CreateJsValue(env, path);
107 }
108 
GetArea(napi_env env,napi_callback_info info)109 napi_value JsApplicationContextUtils::GetArea(napi_env env, napi_callback_info info)
110 {
111     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetArea, APPLICATION_CONTEXT_NAME);
112 }
113 
OnGetArea(napi_env env,NapiCallbackInfo & info)114 napi_value JsApplicationContextUtils::OnGetArea(napi_env env, NapiCallbackInfo &info)
115 {
116     auto context = context_.lock();
117     if (!context) {
118         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
119         return CreateJsUndefined(env);
120     }
121     int area = context->GetArea();
122     return CreateJsValue(env, area);
123 }
124 
GetCacheDir(napi_env env,napi_callback_info info)125 napi_value JsApplicationContextUtils::GetCacheDir(napi_env env, napi_callback_info info)
126 {
127     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetCacheDir, APPLICATION_CONTEXT_NAME);
128 }
129 
OnGetCacheDir(napi_env env,NapiCallbackInfo & info)130 napi_value JsApplicationContextUtils::OnGetCacheDir(napi_env env, NapiCallbackInfo &info)
131 {
132     auto context = context_.lock();
133     if (!context) {
134         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
135         return CreateJsUndefined(env);
136     }
137     std::string path = context->GetCacheDir();
138     return CreateJsValue(env, path);
139 }
140 
GetFilesDir(napi_env env,napi_callback_info info)141 napi_value JsApplicationContextUtils::GetFilesDir(napi_env env, napi_callback_info info)
142 {
143     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetFilesDir, APPLICATION_CONTEXT_NAME);
144 }
145 
OnGetFilesDir(napi_env env,NapiCallbackInfo & info)146 napi_value JsApplicationContextUtils::OnGetFilesDir(napi_env env, NapiCallbackInfo &info)
147 {
148     auto context = context_.lock();
149     if (!context) {
150         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
151         return CreateJsUndefined(env);
152     }
153     std::string path = context->GetFilesDir();
154     return CreateJsValue(env, path);
155 }
156 
GetDistributedFilesDir(napi_env env,napi_callback_info info)157 napi_value JsApplicationContextUtils::GetDistributedFilesDir(napi_env env, napi_callback_info info)
158 {
159     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
160         OnGetDistributedFilesDir, APPLICATION_CONTEXT_NAME);
161 }
162 
OnGetDistributedFilesDir(napi_env env,NapiCallbackInfo & info)163 napi_value JsApplicationContextUtils::OnGetDistributedFilesDir(napi_env env, NapiCallbackInfo &info)
164 {
165     auto context = context_.lock();
166     if (!context) {
167         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
168         return CreateJsUndefined(env);
169     }
170     std::string path = context->GetDistributedFilesDir();
171     return CreateJsValue(env, path);
172 }
173 
GetDatabaseDir(napi_env env,napi_callback_info info)174 napi_value JsApplicationContextUtils::GetDatabaseDir(napi_env env, napi_callback_info info)
175 {
176     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetDatabaseDir, APPLICATION_CONTEXT_NAME);
177 }
178 
OnGetDatabaseDir(napi_env env,NapiCallbackInfo & info)179 napi_value JsApplicationContextUtils::OnGetDatabaseDir(napi_env env, NapiCallbackInfo &info)
180 {
181     auto context = context_.lock();
182     if (!context) {
183         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
184         return CreateJsUndefined(env);
185     }
186     std::string path = context->GetDatabaseDir();
187     return CreateJsValue(env, path);
188 }
189 
GetPreferencesDir(napi_env env,napi_callback_info info)190 napi_value JsApplicationContextUtils::GetPreferencesDir(napi_env env, napi_callback_info info)
191 {
192     GET_NAPI_INFO_WITH_NAME_AND_CALL(env,
193         info, JsApplicationContextUtils, OnGetPreferencesDir, APPLICATION_CONTEXT_NAME);
194 }
195 
OnGetPreferencesDir(napi_env env,NapiCallbackInfo & info)196 napi_value JsApplicationContextUtils::OnGetPreferencesDir(napi_env env, NapiCallbackInfo &info)
197 {
198     auto context = context_.lock();
199     if (!context) {
200         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
201         return CreateJsUndefined(env);
202     }
203     std::string path = context->GetPreferencesDir();
204     return CreateJsValue(env, path);
205 }
206 
GetBundleCodeDir(napi_env env,napi_callback_info info)207 napi_value JsApplicationContextUtils::GetBundleCodeDir(napi_env env, napi_callback_info info)
208 {
209     GET_NAPI_INFO_WITH_NAME_AND_CALL(env,
210         info, JsApplicationContextUtils, OnGetBundleCodeDir, APPLICATION_CONTEXT_NAME);
211 }
212 
OnGetBundleCodeDir(napi_env env,NapiCallbackInfo & info)213 napi_value JsApplicationContextUtils::OnGetBundleCodeDir(napi_env env, NapiCallbackInfo &info)
214 {
215     auto context = context_.lock();
216     if (!context) {
217         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
218         return CreateJsUndefined(env);
219     }
220     std::string path = context->GetBundleCodeDir();
221     return CreateJsValue(env, path);
222 }
223 
GetCloudFileDir(napi_env env,napi_callback_info info)224 napi_value JsApplicationContextUtils::GetCloudFileDir(napi_env env, napi_callback_info info)
225 {
226     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
227         OnGetCloudFileDir, APPLICATION_CONTEXT_NAME);
228 }
229 
OnGetCloudFileDir(napi_env env,NapiCallbackInfo & info)230 napi_value JsApplicationContextUtils::OnGetCloudFileDir(napi_env env, NapiCallbackInfo &info)
231 {
232     auto context = context_.lock();
233     if (!context) {
234         TAG_LOGW(AAFwkTag::ABILITY_SIM, "context released");
235         return CreateJsUndefined(env);
236     }
237     std::string path = context->GetCloudFileDir();
238     return CreateJsValue(env, path);
239 }
240 
KillProcessBySelf(napi_env env,napi_callback_info info)241 napi_value JsApplicationContextUtils::KillProcessBySelf(napi_env env, napi_callback_info info)
242 {
243     return nullptr;
244 }
245 
GetRunningProcessInformation(napi_env env,napi_callback_info info)246 napi_value JsApplicationContextUtils::GetRunningProcessInformation(napi_env env, napi_callback_info info)
247 {
248     return nullptr;
249 }
250 
Finalizer(napi_env env,void * data,void * hint)251 void JsApplicationContextUtils::Finalizer(napi_env env, void *data, void *hint)
252 {
253     std::unique_ptr<JsApplicationContextUtils>(static_cast<JsApplicationContextUtils *>(data));
254 }
255 
RegisterAbilityLifecycleCallback(napi_env env,napi_callback_info info)256 napi_value JsApplicationContextUtils::RegisterAbilityLifecycleCallback(napi_env env, napi_callback_info info)
257 {
258     return nullptr;
259 }
260 
UnregisterAbilityLifecycleCallback(napi_env env,napi_callback_info info)261 napi_value JsApplicationContextUtils::UnregisterAbilityLifecycleCallback(
262     napi_env env, napi_callback_info info)
263 {
264     return nullptr;
265 }
266 
RegisterEnvironmentCallback(napi_env env,napi_callback_info info)267 napi_value JsApplicationContextUtils::RegisterEnvironmentCallback(napi_env env, napi_callback_info info)
268 {
269     return nullptr;
270 }
271 
UnregisterEnvironmentCallback(napi_env env,napi_callback_info info)272 napi_value JsApplicationContextUtils::UnregisterEnvironmentCallback(
273     napi_env env, napi_callback_info info)
274 {
275     return nullptr;
276 }
277 
On(napi_env env,napi_callback_info info)278 napi_value JsApplicationContextUtils::On(napi_env env, napi_callback_info info)
279 {
280     return nullptr;
281 }
282 
Off(napi_env env,napi_callback_info info)283 napi_value JsApplicationContextUtils::Off(napi_env env, napi_callback_info info)
284 {
285     return nullptr;
286 }
287 
GetApplicationContext(napi_env env,napi_callback_info info)288 napi_value JsApplicationContextUtils::GetApplicationContext(napi_env env, napi_callback_info info)
289 {
290     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
291         OnGetApplicationContext, APPLICATION_CONTEXT_NAME);
292 }
293 
OnGetApplicationContext(napi_env env,NapiCallbackInfo & info)294 napi_value JsApplicationContextUtils::OnGetApplicationContext(napi_env env, NapiCallbackInfo &info)
295 {
296     napi_value value = CreateJsApplicationContext(env, context_.lock());
297     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.ApplicationContext", &value, 1);
298     if (systemModule == nullptr) {
299         TAG_LOGW(AAFwkTag::ABILITY_SIM, "null systemModule");
300         return CreateJsUndefined(env);
301     }
302     return systemModule->GetNapiValue();
303 }
304 
CreateJsApplicationContext(napi_env env,const std::shared_ptr<Context> & context)305 napi_value JsApplicationContextUtils::CreateJsApplicationContext(
306     napi_env env, const std::shared_ptr<Context> &context)
307 {
308     TAG_LOGD(AAFwkTag::ABILITY_SIM, "called");
309     napi_value object = nullptr;
310     napi_create_object(env, &object);
311     if (object == nullptr) {
312         return object;
313     }
314 
315     auto jsApplicationContextUtils = std::make_unique<JsApplicationContextUtils>(context);
316     SetNamedNativePointer(env, object, APPLICATION_CONTEXT_NAME, jsApplicationContextUtils.release(),
317         JsApplicationContextUtils::Finalizer);
318 
319     auto appInfo = context->GetApplicationInfo();
320     if (appInfo != nullptr) {
321         napi_set_named_property(env, object, "applicationInfo", CreateJsApplicationInfo(env, *appInfo));
322     }
323 
324     BindNativeApplicationContext(env, object);
325 
326     return object;
327 }
328 
BindNativeApplicationContext(napi_env env,napi_value object)329 void JsApplicationContextUtils::BindNativeApplicationContext(napi_env env, napi_value object)
330 {
331     BindNativeProperty(env, object, "cacheDir", JsApplicationContextUtils::GetCacheDir);
332     BindNativeProperty(env, object, "tempDir", JsApplicationContextUtils::GetTempDir);
333     BindNativeProperty(env, object, "resourceDir", JsApplicationContextUtils::GetResourceDir);
334     BindNativeProperty(env, object, "filesDir", JsApplicationContextUtils::GetFilesDir);
335     BindNativeProperty(env, object, "distributedFilesDir", JsApplicationContextUtils::GetDistributedFilesDir);
336     BindNativeProperty(env, object, "databaseDir", JsApplicationContextUtils::GetDatabaseDir);
337     BindNativeProperty(env, object, "preferencesDir", JsApplicationContextUtils::GetPreferencesDir);
338     BindNativeProperty(env, object, "bundleCodeDir", JsApplicationContextUtils::GetBundleCodeDir);
339     BindNativeProperty(env, object, "cloudFileDir", JsApplicationContextUtils::GetCloudFileDir);
340     BindNativeFunction(env, object, "registerAbilityLifecycleCallback", MD_NAME,
341         JsApplicationContextUtils::RegisterAbilityLifecycleCallback);
342     BindNativeFunction(env, object, "unregisterAbilityLifecycleCallback", MD_NAME,
343         JsApplicationContextUtils::UnregisterAbilityLifecycleCallback);
344     BindNativeFunction(env, object, "registerEnvironmentCallback", MD_NAME,
345         JsApplicationContextUtils::RegisterEnvironmentCallback);
346     BindNativeFunction(env, object, "unregisterEnvironmentCallback", MD_NAME,
347         JsApplicationContextUtils::UnregisterEnvironmentCallback);
348     BindNativeFunction(env, object, "createBundleContext", MD_NAME, JsApplicationContextUtils::CreateBundleContext);
349     BindNativeFunction(env, object, "switchArea", MD_NAME, JsApplicationContextUtils::SwitchArea);
350     BindNativeFunction(env, object, "getArea", MD_NAME, JsApplicationContextUtils::GetArea);
351     BindNativeFunction(env, object, "createModuleContext", MD_NAME, JsApplicationContextUtils::CreateModuleContext);
352     BindNativeFunction(env, object, "createModuleResourceManager", MD_NAME,
353         JsApplicationContextUtils::CreateModuleResourceManager);
354     BindNativeFunction(env, object, "on", MD_NAME, JsApplicationContextUtils::On);
355     BindNativeFunction(env, object, "off", MD_NAME, JsApplicationContextUtils::Off);
356     BindNativeFunction(env, object, "getApplicationContext", MD_NAME,
357         JsApplicationContextUtils::GetApplicationContext);
358     BindNativeFunction(env, object, "killAllProcesses", MD_NAME, JsApplicationContextUtils::KillProcessBySelf);
359     BindNativeFunction(env, object, "getProcessRunningInformation", MD_NAME,
360         JsApplicationContextUtils::GetRunningProcessInformation);
361     BindNativeFunction(env, object, "getRunningProcessInformation", MD_NAME,
362         JsApplicationContextUtils::GetRunningProcessInformation);
363     BindNativeFunction(env, object, "setColorMode", MD_NAME, JsApplicationContextUtils::SetColorMode);
364 }
365 } // namespace AbilityRuntime
366 } // namespace OHOS
367