• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 
20 #include "ability_business_error.h"
21 #include "ability_manager_client.h"
22 #include "ability_manager_interface.h"
23 #include "ability_runtime_error_util.h"
24 #include "application_context.h"
25 #include "application_info.h"
26 #include "application_context_manager.h"
27 #include "hilog_tag_wrapper.h"
28 #include "ipc_skeleton.h"
29 #include "js_ability_auto_startup_callback.h"
30 #include "js_ability_auto_startup_manager_utils.h"
31 #include "js_context_utils.h"
32 #include "js_data_struct_converter.h"
33 #include "js_error_utils.h"
34 #include "js_resource_manager_utils.h"
35 #include "js_runtime_utils.h"
36 #include "napi_common_want.h"
37 #include "tokenid_kit.h"
38 
39 namespace OHOS {
40 namespace AbilityRuntime {
41 namespace {
42 constexpr char APPLICATION_CONTEXT_NAME[] = "__application_context_ptr__";
43 constexpr size_t ARGC_ZERO = 0;
44 constexpr size_t ARGC_ONE = 1;
45 constexpr size_t ARGC_TWO = 2;
46 constexpr size_t ARGC_THREE = 3;
47 constexpr size_t INDEX_ZERO = 0;
48 constexpr size_t INDEX_ONE = 1;
49 constexpr size_t INDEX_TWO = 2;
50 constexpr int32_t ERROR_CODE_ONE = 1;
51 constexpr double FOUNT_SIZE = 0.0;
52 const char* MD_NAME = "JsApplicationContextUtils";
53 }  // namespace
54 
CreateBundleContext(napi_env env,napi_callback_info info)55 napi_value JsApplicationContextUtils::CreateBundleContext(napi_env env, napi_callback_info info)
56 {
57     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
58         OnCreateBundleContext, APPLICATION_CONTEXT_NAME);
59 }
60 
OnCreateBundleContext(napi_env env,NapiCallbackInfo & info)61 napi_value JsApplicationContextUtils::OnCreateBundleContext(napi_env env, NapiCallbackInfo& info)
62 {
63     if (!CheckCallerIsSystemApp()) {
64         TAG_LOGE(AAFwkTag::APPKIT, "This application is not system-app, can not use system-api.");
65         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
66         return CreateJsUndefined(env);
67     }
68     if (info.argc == 0) {
69         TAG_LOGE(AAFwkTag::APPKIT, "Not enough arguments");
70         ThrowInvalidParamError(env, "Not enough params.");
71         return CreateJsUndefined(env);
72     }
73     auto applicationContext = applicationContext_.lock();
74     if (!applicationContext) {
75         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
76         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
77         return CreateJsUndefined(env);
78     }
79     std::string bundleName;
80     if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
81         TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
82         ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
83         return CreateJsUndefined(env);
84     }
85     auto bundleContext = applicationContext->CreateBundleContext(bundleName);
86     if (!bundleContext) {
87         TAG_LOGE(AAFwkTag::APPKIT, "bundleContext is nullptr");
88         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
89         return CreateJsUndefined(env);
90     }
91     napi_value value = CreateJsBaseContext(env, bundleContext, true);
92     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
93     if (systemModule == nullptr) {
94         TAG_LOGW(AAFwkTag::APPKIT, "invalid systemModule.");
95         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
96         return CreateJsUndefined(env);
97     }
98     napi_value contextObj = systemModule->GetNapiValue();
99     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
100         TAG_LOGE(AAFwkTag::APPKIT, "Failed to get context native object");
101         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
102         return CreateJsUndefined(env);
103     }
104     auto workContext = new (std::nothrow) std::weak_ptr<Context>(bundleContext);
105     napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
106     auto res = napi_wrap(env, contextObj, workContext,
107         [](napi_env, void *data, void *) {
108             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr bundle context is called");
109             delete static_cast<std::weak_ptr<Context> *>(data);
110         },
111         nullptr, nullptr);
112     if (res != napi_ok && workContext != nullptr) {
113         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
114         delete workContext;
115         return CreateJsUndefined(env);
116     }
117     return contextObj;
118 }
119 
SwitchArea(napi_env env,napi_callback_info info)120 napi_value JsApplicationContextUtils::SwitchArea(napi_env env, napi_callback_info info)
121 {
122     TAG_LOGD(AAFwkTag::APPKIT, "called");
123     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnSwitchArea, APPLICATION_CONTEXT_NAME);
124 }
125 
OnSwitchArea(napi_env env,NapiCallbackInfo & info)126 napi_value JsApplicationContextUtils::OnSwitchArea(napi_env env, NapiCallbackInfo& info)
127 {
128     if (info.argc == 0) {
129         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
130         return CreateJsUndefined(env);
131     }
132 
133     auto applicationContext = applicationContext_.lock();
134     if (!applicationContext) {
135         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
136         return CreateJsUndefined(env);
137     }
138 
139     int mode = 0;
140     if (!ConvertFromJsValue(env, info.argv[0], mode)) {
141         TAG_LOGE(AAFwkTag::APPKIT, "Parse mode failed");
142         return CreateJsUndefined(env);
143     }
144 
145     applicationContext->SwitchArea(mode);
146 
147     napi_value object = info.thisVar;
148     if (!CheckTypeForNapiValue(env, object, napi_object)) {
149         TAG_LOGE(AAFwkTag::APPKIT, "Check type failed");
150         return CreateJsUndefined(env);
151     }
152     BindNativeProperty(env, object, "cacheDir", GetCacheDir);
153     BindNativeProperty(env, object, "tempDir", GetTempDir);
154     BindNativeProperty(env, object, "resourceDir", GetResourceDir);
155     BindNativeProperty(env, object, "filesDir", GetFilesDir);
156     BindNativeProperty(env, object, "distributedFilesDir", GetDistributedFilesDir);
157     BindNativeProperty(env, object, "databaseDir", GetDatabaseDir);
158     BindNativeProperty(env, object, "preferencesDir", GetPreferencesDir);
159     BindNativeProperty(env, object, "bundleCodeDir", GetBundleCodeDir);
160     BindNativeProperty(env, object, "cloudFileDir", GetCloudFileDir);
161     return CreateJsUndefined(env);
162 }
163 
164 
CreateModuleContext(napi_env env,napi_callback_info info)165 napi_value JsApplicationContextUtils::CreateModuleContext(napi_env env, napi_callback_info info)
166 {
167     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
168         OnCreateModuleContext, APPLICATION_CONTEXT_NAME);
169 }
170 
OnCreateModuleContext(napi_env env,NapiCallbackInfo & info)171 napi_value JsApplicationContextUtils::OnCreateModuleContext(napi_env env, NapiCallbackInfo& info)
172 {
173     auto applicationContext = applicationContext_.lock();
174     if (!applicationContext) {
175         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
176         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
177         return CreateJsUndefined(env);
178     }
179 
180     std::string moduleName;
181     std::shared_ptr<Context> moduleContext = nullptr;
182     if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
183         TAG_LOGD(AAFwkTag::APPKIT, "Parse inner module name.");
184         if (!ConvertFromJsValue(env, info.argv[0], moduleName)) {
185             TAG_LOGE(AAFwkTag::APPKIT, "Parse moduleName failed");
186             ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
187             return CreateJsUndefined(env);
188         }
189         moduleContext = applicationContext->CreateModuleContext(moduleName);
190     } else {
191         std::string bundleName;
192         if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
193             TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
194             ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
195             return CreateJsUndefined(env);
196         }
197         if (!CheckCallerIsSystemApp()) {
198             TAG_LOGE(AAFwkTag::APPKIT, "This application is not system-app, can not use system-api");
199             AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
200             return CreateJsUndefined(env);
201         }
202         TAG_LOGI(AAFwkTag::APPKIT, "Parse outer module name.");
203         moduleContext = applicationContext->CreateModuleContext(bundleName, moduleName);
204     }
205 
206     if (!moduleContext) {
207         TAG_LOGE(AAFwkTag::APPKIT, "failed to create module context.");
208         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
209         return CreateJsUndefined(env);
210     }
211     return CreateJsModuleContext(env, moduleContext);
212 }
213 
CreateJsModuleContext(napi_env env,const std::shared_ptr<Context> & moduleContext)214 napi_value JsApplicationContextUtils::CreateJsModuleContext(napi_env env, const std::shared_ptr<Context>& moduleContext)
215 {
216     napi_value value = CreateJsBaseContext(env, moduleContext, true);
217     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.Context", &value, 1);
218     if (systemModule == nullptr) {
219         TAG_LOGW(AAFwkTag::APPKIT, "invalid systemModule.");
220         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
221         return CreateJsUndefined(env);
222     }
223     napi_value contextObj = systemModule->GetNapiValue();
224     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
225         TAG_LOGE(AAFwkTag::APPKIT, "Failed to get context native object");
226         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
227         return CreateJsUndefined(env);
228     }
229     auto workContext = new (std::nothrow) std::weak_ptr<Context>(moduleContext);
230     napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachBaseContext, workContext, nullptr);
231     auto res = napi_wrap(env, contextObj, workContext,
232         [](napi_env, void *data, void *) {
233             TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr module context is called");
234             delete static_cast<std::weak_ptr<Context> *>(data);
235         },
236         nullptr, nullptr);
237     if (res != napi_ok && workContext != nullptr) {
238         TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
239         delete workContext;
240         return CreateJsUndefined(env);
241     }
242     return contextObj;
243 }
244 
CreateSystemHspModuleResourceManager(napi_env env,napi_callback_info info)245 napi_value JsApplicationContextUtils::CreateSystemHspModuleResourceManager(napi_env env, napi_callback_info info)
246 {
247     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
248         OnCreateSystemHspModuleResourceManager, APPLICATION_CONTEXT_NAME);
249 }
250 
OnCreateSystemHspModuleResourceManager(napi_env env,NapiCallbackInfo & info)251 napi_value JsApplicationContextUtils::OnCreateSystemHspModuleResourceManager(napi_env env, NapiCallbackInfo& info)
252 {
253     auto applicationContext = applicationContext_.lock();
254     if (!applicationContext) {
255         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
256         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
257         return CreateJsUndefined(env);
258     }
259 
260     std::string bundleName = "";
261     if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
262         TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
263         ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
264         return CreateJsUndefined(env);
265     }
266     std::string moduleName = "";
267     if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
268         TAG_LOGD(AAFwkTag::APPKIT, "Parse module name failed.");
269         ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
270         return CreateJsUndefined(env);
271     }
272 
273     std::shared_ptr<Global::Resource::ResourceManager> resourceManager = nullptr;
274     int32_t retCode = applicationContext->CreateSystemHspModuleResourceManager(bundleName, moduleName, resourceManager);
275     if (resourceManager == nullptr && retCode == ERR_ABILITY_RUNTIME_EXTERNAL_NOT_SYSTEM_HSP) {
276         TAG_LOGE(AAFwkTag::APPKIT, "Failed to create resourceManager");
277         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_NOT_SYSTEM_HSP);
278         return CreateJsUndefined(env);
279     }
280     if (resourceManager == nullptr) {
281         TAG_LOGE(AAFwkTag::APPKIT, "Failed to create resourceManager");
282         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
283         return CreateJsUndefined(env);
284     }
285     return CreateJsResourceManager(env, resourceManager, nullptr);
286 }
287 
CreateModuleResourceManager(napi_env env,napi_callback_info info)288 napi_value JsApplicationContextUtils::CreateModuleResourceManager(napi_env env, napi_callback_info info)
289 {
290     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
291         OnCreateModuleResourceManager, APPLICATION_CONTEXT_NAME);
292 }
293 
OnCreateModuleResourceManager(napi_env env,NapiCallbackInfo & info)294 napi_value JsApplicationContextUtils::OnCreateModuleResourceManager(napi_env env, NapiCallbackInfo& info)
295 {
296     auto applicationContext = applicationContext_.lock();
297     if (!applicationContext) {
298         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
299         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
300         return CreateJsUndefined(env);
301     }
302 
303     std::string bundleName;
304     if (!ConvertFromJsValue(env, info.argv[0], bundleName)) {
305         TAG_LOGE(AAFwkTag::APPKIT, "Parse bundleName failed");
306         ThrowInvalidParamError(env, "Parse param bundleName failed, bundleName must be string.");
307         return CreateJsUndefined(env);
308     }
309     std::string moduleName;
310     if (!ConvertFromJsValue(env, info.argv[1], moduleName)) {
311         TAG_LOGE(AAFwkTag::APPKIT, "Parse moduleName failed");
312         ThrowInvalidParamError(env, "Parse param moduleName failed, moduleName must be string.");
313         return CreateJsUndefined(env);
314     }
315     if (!CheckCallerIsSystemApp()) {
316         TAG_LOGE(AAFwkTag::APPKIT, "This application is not system-app, can not use system-api");
317         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_NOT_SYSTEM_APP);
318         return CreateJsUndefined(env);
319     }
320     auto resourceManager = applicationContext->CreateModuleResourceManager(bundleName, moduleName);
321     if (resourceManager == nullptr) {
322         TAG_LOGE(AAFwkTag::APPKIT, "Failed to create resourceManager");
323         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
324         return CreateJsUndefined(env);
325     }
326     auto jsResourceManager = CreateJsResourceManager(env, resourceManager, nullptr);
327     return jsResourceManager;
328 }
329 
GetArea(napi_env env,napi_callback_info info)330 napi_value JsApplicationContextUtils::GetArea(napi_env env, napi_callback_info info)
331 {
332     TAG_LOGD(AAFwkTag::APPKIT, "called");
333     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetArea, APPLICATION_CONTEXT_NAME);
334 }
335 
OnGetArea(napi_env env,NapiCallbackInfo & info)336 napi_value JsApplicationContextUtils::OnGetArea(napi_env env, NapiCallbackInfo& info)
337 {
338     auto applicationContext = applicationContext_.lock();
339     if (!applicationContext) {
340         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
341         return CreateJsUndefined(env);
342     }
343     int area = applicationContext->GetArea();
344     return CreateJsValue(env, area);
345 }
346 
GetCacheDir(napi_env env,napi_callback_info info)347 napi_value JsApplicationContextUtils::GetCacheDir(napi_env env, napi_callback_info info)
348 {
349     TAG_LOGD(AAFwkTag::APPKIT, "called");
350     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetCacheDir, APPLICATION_CONTEXT_NAME);
351 }
352 
OnGetCacheDir(napi_env env,NapiCallbackInfo & info)353 napi_value JsApplicationContextUtils::OnGetCacheDir(napi_env env, NapiCallbackInfo& info)
354 {
355     auto applicationContext = applicationContext_.lock();
356     if (!applicationContext) {
357         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
358         return CreateJsUndefined(env);
359     }
360     std::string path = applicationContext->GetCacheDir();
361     return CreateJsValue(env, path);
362 }
363 
GetTempDir(napi_env env,napi_callback_info info)364 napi_value JsApplicationContextUtils::GetTempDir(napi_env env, napi_callback_info info)
365 {
366     TAG_LOGD(AAFwkTag::APPKIT, "called");
367     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetTempDir, APPLICATION_CONTEXT_NAME);
368 }
369 
OnGetTempDir(napi_env env,NapiCallbackInfo & info)370 napi_value JsApplicationContextUtils::OnGetTempDir(napi_env env, NapiCallbackInfo& info)
371 {
372     auto applicationContext = applicationContext_.lock();
373     if (!applicationContext) {
374         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
375         return CreateJsUndefined(env);
376     }
377     std::string path = applicationContext->GetTempDir();
378     return CreateJsValue(env, path);
379 }
380 
GetResourceDir(napi_env env,napi_callback_info info)381 napi_value JsApplicationContextUtils::GetResourceDir(napi_env env, napi_callback_info info)
382 {
383     TAG_LOGD(AAFwkTag::APPKIT, "called");
384     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetResourceDir, APPLICATION_CONTEXT_NAME);
385 }
386 
OnGetResourceDir(napi_env env,NapiCallbackInfo & info)387 napi_value JsApplicationContextUtils::OnGetResourceDir(napi_env env, NapiCallbackInfo& info)
388 {
389     auto applicationContext = applicationContext_.lock();
390     if (!applicationContext) {
391         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
392         return CreateJsUndefined(env);
393     }
394     std::string path = applicationContext->GetResourceDir();
395     return CreateJsValue(env, path);
396 }
397 
GetFilesDir(napi_env env,napi_callback_info info)398 napi_value JsApplicationContextUtils::GetFilesDir(napi_env env, napi_callback_info info)
399 {
400     TAG_LOGD(AAFwkTag::APPKIT, "called");
401     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetFilesDir, APPLICATION_CONTEXT_NAME);
402 }
403 
OnGetFilesDir(napi_env env,NapiCallbackInfo & info)404 napi_value JsApplicationContextUtils::OnGetFilesDir(napi_env env, NapiCallbackInfo& info)
405 {
406     auto applicationContext = applicationContext_.lock();
407     if (!applicationContext) {
408         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
409         return CreateJsUndefined(env);
410     }
411     std::string path = applicationContext->GetFilesDir();
412     return CreateJsValue(env, path);
413 }
414 
GetDistributedFilesDir(napi_env env,napi_callback_info info)415 napi_value JsApplicationContextUtils::GetDistributedFilesDir(napi_env env, napi_callback_info info)
416 {
417     TAG_LOGD(AAFwkTag::APPKIT, "called");
418     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
419         OnGetDistributedFilesDir, APPLICATION_CONTEXT_NAME);
420 }
421 
OnGetDistributedFilesDir(napi_env env,NapiCallbackInfo & info)422 napi_value JsApplicationContextUtils::OnGetDistributedFilesDir(napi_env env, NapiCallbackInfo& info)
423 {
424     auto applicationContext = applicationContext_.lock();
425     if (!applicationContext) {
426         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
427         return CreateJsUndefined(env);
428     }
429     std::string path = applicationContext->GetDistributedFilesDir();
430     return CreateJsValue(env, path);
431 }
432 
GetCloudFileDir(napi_env env,napi_callback_info info)433 napi_value JsApplicationContextUtils::GetCloudFileDir(napi_env env, napi_callback_info info)
434 {
435     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
436         OnGetCloudFileDir, APPLICATION_CONTEXT_NAME);
437 }
438 
OnGetCloudFileDir(napi_env env,NapiCallbackInfo & info)439 napi_value JsApplicationContextUtils::OnGetCloudFileDir(napi_env env, NapiCallbackInfo& info)
440 {
441     auto applicationContext = applicationContext_.lock();
442     if (!applicationContext) {
443         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
444         return CreateJsUndefined(env);
445     }
446     std::string path = applicationContext->GetCloudFileDir();
447     return CreateJsValue(env, path);
448 }
449 
GetDatabaseDir(napi_env env,napi_callback_info info)450 napi_value JsApplicationContextUtils::GetDatabaseDir(napi_env env, napi_callback_info info)
451 {
452     TAG_LOGD(AAFwkTag::APPKIT, "called");
453     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetDatabaseDir, APPLICATION_CONTEXT_NAME);
454 }
455 
OnGetDatabaseDir(napi_env env,NapiCallbackInfo & info)456 napi_value JsApplicationContextUtils::OnGetDatabaseDir(napi_env env, NapiCallbackInfo& info)
457 {
458     auto applicationContext = applicationContext_.lock();
459     if (!applicationContext) {
460         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
461         return CreateJsUndefined(env);
462     }
463     std::string path = applicationContext->GetDatabaseDir();
464     return CreateJsValue(env, path);
465 }
466 
GetPreferencesDir(napi_env env,napi_callback_info info)467 napi_value JsApplicationContextUtils::GetPreferencesDir(napi_env env, napi_callback_info info)
468 {
469     TAG_LOGD(AAFwkTag::APPKIT, "called");
470     GET_NAPI_INFO_WITH_NAME_AND_CALL(
471         env, info, JsApplicationContextUtils, OnGetPreferencesDir, APPLICATION_CONTEXT_NAME);
472 }
473 
GetGroupDir(napi_env env,napi_callback_info info)474 napi_value JsApplicationContextUtils::GetGroupDir(napi_env env, napi_callback_info info)
475 {
476     TAG_LOGD(AAFwkTag::APPKIT, "called");
477     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnGetGroupDir, APPLICATION_CONTEXT_NAME);
478 }
479 
OnGetPreferencesDir(napi_env env,NapiCallbackInfo & info)480 napi_value JsApplicationContextUtils::OnGetPreferencesDir(napi_env env, NapiCallbackInfo& info)
481 {
482     auto applicationContext = applicationContext_.lock();
483     if (!applicationContext) {
484         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
485         return CreateJsUndefined(env);
486     }
487     std::string path = applicationContext->GetPreferencesDir();
488     return CreateJsValue(env, path);
489 }
490 
OnGetGroupDir(napi_env env,NapiCallbackInfo & info)491 napi_value JsApplicationContextUtils::OnGetGroupDir(napi_env env, NapiCallbackInfo& info)
492 {
493     if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
494         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
495         ThrowInvalidParamError(env, "Not enough params.");
496         return CreateJsUndefined(env);
497     }
498 
499     std::string groupId;
500     if (!ConvertFromJsValue(env, info.argv[0], groupId)) {
501         TAG_LOGE(AAFwkTag::APPKIT, "Parse groupId failed");
502         ThrowInvalidParamError(env, "Parse param groupId failed, groupId must be string.");
503         return CreateJsUndefined(env);
504     }
505 
506     TAG_LOGD(AAFwkTag::APPKIT, "Get Group Dir");
507     auto complete = [applicationContext = applicationContext_, groupId]
508         (napi_env env, NapiAsyncTask& task, int32_t status) {
509         auto context = applicationContext.lock();
510         if (!context) {
511             task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST,
512                 "applicationContext if already released."));
513             return;
514         }
515         std::string path = context->GetGroupDir(groupId);
516         task.ResolveWithNoError(env, CreateJsValue(env, path));
517     };
518 
519     napi_value lastParam = (info.argc == ARGC_TWO) ? info.argv[INDEX_ONE] : nullptr;
520     napi_value result = nullptr;
521     NapiAsyncTask::ScheduleHighQos("JsApplicationContextUtils::OnGetGroupDir",
522         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
523     return result;
524 }
525 
RestartApp(napi_env env,napi_callback_info info)526 napi_value JsApplicationContextUtils::RestartApp(napi_env env, napi_callback_info info)
527 {
528     TAG_LOGD(AAFwkTag::APPKIT, "called");
529     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnRestartApp, APPLICATION_CONTEXT_NAME);
530 }
531 
OnRestartApp(napi_env env,NapiCallbackInfo & info)532 napi_value JsApplicationContextUtils::OnRestartApp(napi_env env, NapiCallbackInfo& info)
533 {
534     // only support one params
535     if (info.argc == ARGC_ZERO) {
536         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
537         ThrowInvalidParamError(env, "Not enough params");
538         return CreateJsUndefined(env);
539     }
540     auto applicationContext = applicationContext_.lock();
541     if (!applicationContext) {
542         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
543         return CreateJsUndefined(env);
544     }
545     AAFwk::Want want;
546     if (!AppExecFwk::UnwrapWant(env, info.argv[INDEX_ZERO], want)) {
547         TAG_LOGE(AAFwkTag::APPKIT, "Parse want failed");
548         ThrowInvalidParamError(env, "Parse param want failed, want must be Want.");
549         return CreateJsUndefined(env);
550     }
551 
552     auto errCode = applicationContext->RestartApp(want);
553     if (errCode == ERR_OK) {
554         return CreateJsUndefined(env);
555     }
556     if (errCode == ERR_INVALID_VALUE) {
557         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
558     } else if (errCode == AAFwk::ERR_RESTART_APP_INCORRECT_ABILITY) {
559         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_RESTART_APP_INCORRECT_ABILITY);
560     } else if (errCode == AAFwk::ERR_RESTART_APP_FREQUENT) {
561         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_RESTART_APP_FREQUENT);
562     } else if (errCode == AAFwk::NOT_TOP_ABILITY) {
563         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_NOT_TOP_ABILITY);
564     } else {
565         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
566     }
567     TAG_LOGE(AAFwkTag::APPKIT, "errCode is %{public}d.", errCode);
568     return CreateJsUndefined(env);
569 }
570 
GetBundleCodeDir(napi_env env,napi_callback_info info)571 napi_value JsApplicationContextUtils::GetBundleCodeDir(napi_env env, napi_callback_info info)
572 {
573     TAG_LOGD(AAFwkTag::APPKIT, "called");
574     GET_NAPI_INFO_WITH_NAME_AND_CALL(
575         env, info, JsApplicationContextUtils, OnGetBundleCodeDir, APPLICATION_CONTEXT_NAME);
576 }
577 
OnGetBundleCodeDir(napi_env env,NapiCallbackInfo & info)578 napi_value JsApplicationContextUtils::OnGetBundleCodeDir(napi_env env, NapiCallbackInfo& info)
579 {
580     auto applicationContext = applicationContext_.lock();
581     if (!applicationContext) {
582         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
583         return CreateJsUndefined(env);
584     }
585     std::string path = applicationContext->GetBundleCodeDir();
586     return CreateJsValue(env, path);
587 }
588 
KillProcessBySelf(napi_env env,napi_callback_info info)589 napi_value JsApplicationContextUtils::KillProcessBySelf(napi_env env, napi_callback_info info)
590 {
591     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
592         OnKillProcessBySelf, APPLICATION_CONTEXT_NAME);
593 }
594 
OnKillProcessBySelf(napi_env env,NapiCallbackInfo & info)595 napi_value JsApplicationContextUtils::OnKillProcessBySelf(napi_env env, NapiCallbackInfo& info)
596 {
597     // only support 0 or 1 params
598     if (info.argc != ARGC_ZERO && info.argc != ARGC_ONE) {
599         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
600         ThrowInvalidParamError(env, "Not enough params.");
601         return CreateJsUndefined(env);
602     }
603     TAG_LOGD(AAFwkTag::APPKIT, "kill self process");
604     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
605     NapiAsyncTask::ExecuteCallback execute =
606         [applicationContext = applicationContext_, innerErrCode]() {
607         auto context = applicationContext.lock();
608         if (!context) {
609             TAG_LOGE(AAFwkTag::APPKIT, "applicationContext is released");
610             *innerErrCode = ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST;
611             return;
612         }
613         context->KillProcessBySelf();
614     };
615     NapiAsyncTask::CompleteCallback complete = [innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) {
616         if (*innerErrCode != ERR_OK) {
617             task.Reject(env, CreateJsError(env, *innerErrCode, "applicationContext is already released."));
618             return;
619         }
620         task.ResolveWithNoError(env, CreateJsUndefined(env));
621     };
622     napi_value lastParam = (info.argc == ARGC_ONE) ? info.argv[INDEX_ZERO] : nullptr;
623     napi_value result = nullptr;
624     NapiAsyncTask::ScheduleHighQos("JsApplicationContextUtils::OnkillProcessBySelf",
625         env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
626     return result;
627 }
628 
SetColorMode(napi_env env,napi_callback_info info)629 napi_value JsApplicationContextUtils::SetColorMode(napi_env env, napi_callback_info info)
630 {
631     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnSetColorMode, APPLICATION_CONTEXT_NAME);
632 }
633 
OnSetColorMode(napi_env env,NapiCallbackInfo & info)634 napi_value JsApplicationContextUtils::OnSetColorMode(napi_env env, NapiCallbackInfo& info)
635 {
636     TAG_LOGD(AAFwkTag::APPKIT, "called");
637     // only support one params
638     if (info.argc == ARGC_ZERO) {
639         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
640         ThrowInvalidParamError(env, "Not enough params.");
641         return CreateJsUndefined(env);
642     }
643     auto applicationContext = applicationContext_.lock();
644     if (applicationContext == nullptr) {
645         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
646         return CreateJsUndefined(env);
647     }
648 
649     int32_t colorMode = 0;
650     if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], colorMode)) {
651         ThrowInvalidParamError(env, "Parse param colorMode failed, colorMode must be number.");
652         TAG_LOGE(AAFwkTag::APPKIT, "Parse colorMode failed");
653         return CreateJsUndefined(env);
654     }
655     applicationContext->SetColorMode(colorMode);
656     return CreateJsUndefined(env);
657 }
658 
SetLanguage(napi_env env,napi_callback_info info)659 napi_value JsApplicationContextUtils::SetLanguage(napi_env env, napi_callback_info info)
660 {
661     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnSetLanguage, APPLICATION_CONTEXT_NAME);
662 }
663 
OnSetLanguage(napi_env env,NapiCallbackInfo & info)664 napi_value JsApplicationContextUtils::OnSetLanguage(napi_env env, NapiCallbackInfo& info)
665 {
666     // only support one params
667     if (info.argc == ARGC_ZERO) {
668         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
669         ThrowInvalidParamError(env, "Not enough params.");
670         return CreateJsUndefined(env);
671     }
672     auto applicationContext = applicationContext_.lock();
673     if (!applicationContext) {
674         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
675         return CreateJsUndefined(env);
676     }
677     std::string language;
678     if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], language)) {
679         TAG_LOGE(AAFwkTag::APPKIT, "Parse language failed");
680         ThrowInvalidParamError(env, "Parse param language failed, language must be string.");
681         return CreateJsUndefined(env);
682     }
683     applicationContext->SetLanguage(language);
684     return CreateJsUndefined(env);
685 }
686 
SetFontSizeScale(napi_env env,napi_callback_info info)687 napi_value JsApplicationContextUtils::SetFontSizeScale(napi_env env, napi_callback_info info)
688 {
689     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
690         OnSetFontSizeScale, APPLICATION_CONTEXT_NAME);
691 }
692 
OnSetFontSizeScale(napi_env env,NapiCallbackInfo & info)693 napi_value JsApplicationContextUtils::OnSetFontSizeScale(napi_env env, NapiCallbackInfo& info)
694 {
695     if (info.argc == ARGC_ZERO) {
696         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
697         ThrowInvalidParamError(env, "Not enough params.");
698         return CreateJsUndefined(env);
699     }
700 
701     auto applicationContext = applicationContext_.lock();
702     if (applicationContext == nullptr) {
703         TAG_LOGE(AAFwkTag::APPKIT, "applicationContext released");
704         ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
705         return CreateJsUndefined(env);
706     }
707 
708     double fontSizeScale = 1;
709     if (!ConvertFromJsNumber(env, info.argv[INDEX_ZERO], fontSizeScale)) {
710         TAG_LOGE(AAFwkTag::APPKIT, "Parse fontSizeScale failed");
711         ThrowInvalidParamError(env, "Parse fontSizeScale failed, fontSizeScale must be number.");
712         return CreateJsUndefined(env);
713     }
714     TAG_LOGD(AAFwkTag::APPKIT, "fontSizeScale: %{public}f", fontSizeScale);
715     if (fontSizeScale < FOUNT_SIZE) {
716         TAG_LOGE(AAFwkTag::APPKIT, "invalid size");
717         ThrowInvalidParamError(env, "Invalid font size.");
718         return CreateJsUndefined(env);
719     }
720 
721     applicationContext->SetFontSizeScale(fontSizeScale);
722     return CreateJsUndefined(env);
723 }
724 
SetFont(napi_env env,napi_callback_info info)725 napi_value JsApplicationContextUtils::SetFont(napi_env env, napi_callback_info info)
726 {
727     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnSetFont, APPLICATION_CONTEXT_NAME);
728 }
729 
OnSetFont(napi_env env,NapiCallbackInfo & info)730 napi_value JsApplicationContextUtils::OnSetFont(napi_env env, NapiCallbackInfo& info)
731 {
732     // only support one params
733     if (info.argc == ARGC_ZERO) {
734         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
735         ThrowInvalidParamError(env, "Not enough params.");
736         return CreateJsUndefined(env);
737     }
738     auto applicationContext = applicationContext_.lock();
739     if (!applicationContext) {
740         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
741         return CreateJsUndefined(env);
742     }
743     std::string font;
744     if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], font)) {
745         TAG_LOGE(AAFwkTag::APPKIT, "Parse font failed");
746         ThrowInvalidParamError(env, "Parse param font failed, font must be string.");
747         return CreateJsUndefined(env);
748     }
749     applicationContext->SetFont(font);
750     return CreateJsUndefined(env);
751 }
752 
PreloadUIExtensionAbility(napi_env env,napi_callback_info info)753 napi_value JsApplicationContextUtils::PreloadUIExtensionAbility(napi_env env, napi_callback_info info)
754 {
755     GET_NAPI_INFO_WITH_NAME_AND_CALL(
756         env, info, JsApplicationContextUtils, OnPreloadUIExtensionAbility, APPLICATION_CONTEXT_NAME);
757 }
758 
OnPreloadUIExtensionAbility(napi_env env,NapiCallbackInfo & info)759 napi_value JsApplicationContextUtils::OnPreloadUIExtensionAbility(napi_env env, NapiCallbackInfo& info)
760 {
761     TAG_LOGD(AAFwkTag::APPKIT, "called");
762     if (info.argc < ARGC_ONE) {
763         TAG_LOGW(AAFwkTag::APPKIT, "Params error!");
764         ThrowTooFewParametersError(env);
765         return CreateJsUndefined(env);
766     }
767 
768     AAFwk::Want want;
769     if (!AppExecFwk::UnwrapWant(env, info.argv[INDEX_ZERO], want)) {
770         TAG_LOGW(AAFwkTag::APPKIT, "Parse want failed");
771         ThrowInvalidParamError(env,
772             "Parse param want failed, want must be Want.");
773         return CreateJsUndefined(env);
774     }
775 
776     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
777     NapiAsyncTask::ExecuteCallback execute = [applicationContext = applicationContext_, want, innerErrCode]() {
778         auto context = applicationContext.lock();
779         if (!context) {
780             TAG_LOGE(AAFwkTag::APPKIT, "applicationContext is released");
781             *innerErrCode = static_cast<int>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
782             return;
783         }
784         auto hostBundleName = context->GetBundleName();
785         TAG_LOGD(AAFwkTag::APPKIT, "HostBundleName is %{public}s", hostBundleName.c_str());
786         *innerErrCode = AAFwk::AbilityManagerClient::GetInstance()->PreloadUIExtensionAbility(want, hostBundleName);
787     };
788     NapiAsyncTask::CompleteCallback complete = [innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) {
789         if (*innerErrCode == ERR_OK) {
790             task.Resolve(env, CreateJsUndefined(env));
791         } else {
792             TAG_LOGE(AAFwkTag::APPKIT, "OnPreloadUIExtensionAbility is failed %{public}d", *innerErrCode);
793             task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode));
794         }
795     };
796     napi_value result = nullptr;
797     NapiAsyncTask::ScheduleHighQos("JsApplicationContextUtils::OnPreloadUIExtensionAbility",
798         env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
799     return result;
800 }
801 
ClearUpApplicationData(napi_env env,napi_callback_info info)802 napi_value JsApplicationContextUtils::ClearUpApplicationData(napi_env env, napi_callback_info info)
803 {
804     GET_NAPI_INFO_WITH_NAME_AND_CALL(
805         env, info, JsApplicationContextUtils, OnClearUpApplicationData, APPLICATION_CONTEXT_NAME);
806 }
807 
OnClearUpApplicationData(napi_env env,NapiCallbackInfo & info)808 napi_value JsApplicationContextUtils::OnClearUpApplicationData(napi_env env, NapiCallbackInfo &info)
809 {
810     // only support 0 or 1 params
811     if (info.argc != ARGC_ZERO && info.argc != ARGC_ONE) {
812         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
813         ThrowInvalidParamError(env, "Not enough params.");
814         return CreateJsUndefined(env);
815     }
816     NapiAsyncTask::CompleteCallback complete =
817         [applicationContext = applicationContext_](napi_env env, NapiAsyncTask& task, int32_t status) {
818             auto context = applicationContext.lock();
819             if (!context) {
820                 task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST,
821                     "applicationContext if already released."));
822                 return;
823             }
824             context->ClearUpApplicationData();
825             task.ResolveWithNoError(env, CreateJsUndefined(env));
826         };
827     napi_value lastParam = (info.argc == ARGC_ONE) ? info.argv[INDEX_ZERO] : nullptr;
828     napi_value result = nullptr;
829     NapiAsyncTask::ScheduleHighQos("JsApplicationContextUtils::OnClearUpApplicationData",
830         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
831     return result;
832 }
833 
GetRunningProcessInformation(napi_env env,napi_callback_info info)834 napi_value JsApplicationContextUtils::GetRunningProcessInformation(napi_env env, napi_callback_info info)
835 {
836     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
837         OnGetRunningProcessInformation, APPLICATION_CONTEXT_NAME);
838 }
839 
OnGetRunningProcessInformation(napi_env env,NapiCallbackInfo & info)840 napi_value JsApplicationContextUtils::OnGetRunningProcessInformation(napi_env env, NapiCallbackInfo& info)
841 {
842     // only support 0 or 1 params
843     if (info.argc != ARGC_ZERO && info.argc != ARGC_ONE) {
844         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
845         ThrowInvalidParamError(env, "Not enough params.");
846         return CreateJsUndefined(env);
847     }
848     TAG_LOGD(AAFwkTag::APPKIT, "Get Process Info");
849     auto complete = [applicationContext = applicationContext_](napi_env env, NapiAsyncTask& task, int32_t status) {
850         auto context = applicationContext.lock();
851         if (!context) {
852             task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST,
853                 "applicationContext if already released."));
854             return;
855         }
856         AppExecFwk::RunningProcessInfo processInfo;
857         auto ret = context->GetProcessRunningInformation(processInfo);
858         if (ret == 0) {
859             napi_value object = nullptr;
860             napi_create_object(env, &object);
861             napi_set_named_property(env, object, "processName", CreateJsValue(env, processInfo.processName_));
862             napi_set_named_property(env, object, "pid", CreateJsValue(env, processInfo.pid_));
863             napi_set_named_property(env, object, "uid", CreateJsValue(env, processInfo.uid_));
864             napi_set_named_property(env, object, "bundleNames", CreateNativeArray(env, processInfo.bundleNames));
865             napi_set_named_property(env, object,
866                 "state", CreateJsValue(env, ConvertToJsAppProcessState(processInfo.state_, processInfo.isFocused)));
867             if (processInfo.appCloneIndex != -1) {
868                 napi_set_named_property(env, object, "appCloneIndex", CreateJsValue(env, processInfo.appCloneIndex));
869             }
870             napi_value array = nullptr;
871             napi_create_array_with_length(env, 1, &array);
872             if (array == nullptr) {
873                 TAG_LOGE(AAFwkTag::APPKIT, "Initiate array failed.");
874                 task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR,
875                     "Initiate array failed."));
876             } else {
877                 napi_set_element(env, array, 0, object);
878                 task.ResolveWithNoError(env, array);
879             }
880         } else {
881             task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR,
882                 "Get process infos failed."));
883         }
884     };
885 
886     napi_value lastParam = (info.argc == ARGC_ONE) ? info.argv[INDEX_ZERO] : nullptr;
887     napi_value result = nullptr;
888     NapiAsyncTask::Schedule("JsApplicationContextUtils::OnGetRunningProcessInformation",
889         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
890     return result;
891 }
892 
GetCurrentAppCloneIndex(napi_env env,napi_callback_info info)893 napi_value JsApplicationContextUtils::GetCurrentAppCloneIndex(napi_env env, napi_callback_info info)
894 {
895     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
896         OnGetCurrentAppCloneIndex, APPLICATION_CONTEXT_NAME);
897 }
898 
OnGetCurrentAppCloneIndex(napi_env env,NapiCallbackInfo & info)899 napi_value JsApplicationContextUtils::OnGetCurrentAppCloneIndex(napi_env env, NapiCallbackInfo& info)
900 {
901     TAG_LOGD(AAFwkTag::APPKIT, "Get App Index");
902     auto context = applicationContext_.lock();
903     if (context == nullptr) {
904         TAG_LOGE(AAFwkTag::APPKIT, "context is nullptr.");
905         ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
906         return CreateJsUndefined(env);
907     }
908     if (context->GetCurrentAppMode() != static_cast<int32_t>(AppExecFwk::MultiAppModeType::APP_CLONE)) {
909         ThrowError(env, AbilityErrorCode::ERROR_NOT_APP_CLONE);
910         return CreateJsUndefined(env);
911     }
912     int32_t appIndex = context->GetCurrentAppCloneIndex();
913     return CreateJsValue(env, appIndex);
914 }
915 
Finalizer(napi_env env,void * data,void * hint)916 void JsApplicationContextUtils::Finalizer(napi_env env, void *data, void *hint)
917 {
918     TAG_LOGD(AAFwkTag::APPKIT, "called");
919     std::unique_ptr<JsApplicationContextUtils>(static_cast<JsApplicationContextUtils *>(data));
920 }
921 
RegisterAbilityLifecycleCallback(napi_env env,napi_callback_info info)922 napi_value JsApplicationContextUtils::RegisterAbilityLifecycleCallback(napi_env env, napi_callback_info info)
923 {
924     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
925         OnRegisterAbilityLifecycleCallback, APPLICATION_CONTEXT_NAME);
926 }
927 
UnregisterAbilityLifecycleCallback(napi_env env,napi_callback_info info)928 napi_value JsApplicationContextUtils::UnregisterAbilityLifecycleCallback(
929     napi_env env, napi_callback_info info)
930 {
931     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
932         OnUnregisterAbilityLifecycleCallback, APPLICATION_CONTEXT_NAME);
933 }
934 
OnRegisterAbilityLifecycleCallback(napi_env env,NapiCallbackInfo & info)935 napi_value JsApplicationContextUtils::OnRegisterAbilityLifecycleCallback(
936     napi_env env, NapiCallbackInfo& info)
937 {
938     TAG_LOGD(AAFwkTag::APPKIT, "called");
939     // only support one params
940     if (info.argc != ARGC_ONE) {
941         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
942         return CreateJsUndefined(env);
943     }
944 
945     auto applicationContext = applicationContext_.lock();
946     if (applicationContext == nullptr) {
947         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
948         return CreateJsUndefined(env);
949     }
950     if (callback_ != nullptr) {
951         TAG_LOGD(AAFwkTag::APPKIT, "callback_ is not nullptr");
952         return CreateJsValue(env, callback_->Register(info.argv[0]));
953     }
954     callback_ = std::make_shared<JsAbilityLifecycleCallback>(env);
955     int32_t callbackId = callback_->Register(info.argv[INDEX_ZERO]);
956     applicationContext->RegisterAbilityLifecycleCallback(callback_);
957     return CreateJsValue(env, callbackId);
958 }
959 
OnUnregisterAbilityLifecycleCallback(napi_env env,NapiCallbackInfo & info)960 napi_value JsApplicationContextUtils::OnUnregisterAbilityLifecycleCallback(
961     napi_env env, NapiCallbackInfo& info)
962 {
963     TAG_LOGD(AAFwkTag::APPKIT, "called");
964     int32_t errCode = 0;
965     auto applicationContext = applicationContext_.lock();
966     if (applicationContext == nullptr) {
967         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
968         errCode = ERROR_CODE_ONE;
969     }
970     int32_t callbackId = -1;
971     if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
972         TAG_LOGE(AAFwkTag::APPKIT, "OnUnregisterAbilityLifecycleCallback, Not enough params");
973         errCode = ERROR_CODE_ONE;
974     } else {
975         napi_get_value_int32(env, info.argv[INDEX_ZERO], &callbackId);
976         TAG_LOGD(AAFwkTag::APPKIT, "callbackId is %{public}d.", callbackId);
977     }
978     std::weak_ptr<JsAbilityLifecycleCallback> callbackWeak(callback_);
979     NapiAsyncTask::CompleteCallback complete = [callbackWeak, callbackId, errCode](
980             napi_env env, NapiAsyncTask &task, int32_t status) {
981             if (errCode != 0) {
982                 task.Reject(env, CreateJsError(env, errCode, "Invalidate params."));
983                 return;
984             }
985             auto callback = callbackWeak.lock();
986             if (callback == nullptr) {
987                 TAG_LOGE(AAFwkTag::APPKIT, "callback is nullptr");
988                 task.Reject(env, CreateJsError(env, ERROR_CODE_ONE, "callback is nullptr"));
989                 return;
990             }
991 
992             TAG_LOGD(AAFwkTag::APPKIT, "OnUnregisterAbilityLifecycleCallback begin");
993             if (!callback->UnRegister(callbackId)) {
994                 TAG_LOGE(AAFwkTag::APPKIT, "call UnRegister failed!");
995                 task.Reject(env, CreateJsError(env, ERROR_CODE_ONE, "call UnRegister failed!"));
996                 return;
997             }
998 
999             task.Resolve(env, CreateJsUndefined(env));
1000         };
1001     napi_value lastParam = (info.argc <= ARGC_ONE) ? nullptr : info.argv[INDEX_ONE];
1002     napi_value result = nullptr;
1003     NapiAsyncTask::Schedule("JsApplicationContextUtils::OnUnregisterAbilityLifecycleCallback", env,
1004         CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1005     return result;
1006 }
1007 
RegisterEnvironmentCallback(napi_env env,napi_callback_info info)1008 napi_value JsApplicationContextUtils::RegisterEnvironmentCallback(napi_env env, napi_callback_info info)
1009 {
1010     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
1011         OnRegisterEnvironmentCallback, APPLICATION_CONTEXT_NAME);
1012 }
1013 
UnregisterEnvironmentCallback(napi_env env,napi_callback_info info)1014 napi_value JsApplicationContextUtils::UnregisterEnvironmentCallback(
1015     napi_env env, napi_callback_info info)
1016 {
1017     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
1018         OnUnregisterEnvironmentCallback, APPLICATION_CONTEXT_NAME);
1019 }
1020 
OnRegisterEnvironmentCallback(napi_env env,NapiCallbackInfo & info)1021 napi_value JsApplicationContextUtils::OnRegisterEnvironmentCallback(
1022     napi_env env, NapiCallbackInfo& info)
1023 {
1024     TAG_LOGD(AAFwkTag::APPKIT, "called");
1025     // only support one params
1026     if (info.argc != ARGC_ONE) {
1027         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
1028         return CreateJsUndefined(env);
1029     }
1030 
1031     auto applicationContext = applicationContext_.lock();
1032     if (applicationContext == nullptr) {
1033         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1034         return CreateJsUndefined(env);
1035     }
1036     if (envCallback_ != nullptr) {
1037         TAG_LOGD(AAFwkTag::APPKIT, "envCallback_ is not nullptr");
1038         return CreateJsValue(env, envCallback_->Register(info.argv[0]));
1039     }
1040     envCallback_ = std::make_shared<JsEnvironmentCallback>(env);
1041     int32_t callbackId = envCallback_->Register(info.argv[INDEX_ZERO]);
1042     applicationContext->RegisterEnvironmentCallback(envCallback_);
1043     return CreateJsValue(env, callbackId);
1044 }
1045 
OnUnregisterEnvironmentCallback(napi_env env,NapiCallbackInfo & info)1046 napi_value JsApplicationContextUtils::OnUnregisterEnvironmentCallback(
1047     napi_env env, NapiCallbackInfo& info)
1048 {
1049     int32_t errCode = 0;
1050     auto applicationContext = applicationContext_.lock();
1051     if (applicationContext == nullptr) {
1052         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1053         errCode = ERROR_CODE_ONE;
1054     }
1055     int32_t callbackId = -1;
1056     if (info.argc != ARGC_ONE && info.argc != ARGC_TWO) {
1057         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
1058         errCode = ERROR_CODE_ONE;
1059     } else {
1060         napi_get_value_int32(env, info.argv[INDEX_ZERO], &callbackId);
1061         TAG_LOGD(AAFwkTag::APPKIT, "callbackId is %{public}d", callbackId);
1062     }
1063     std::weak_ptr<JsEnvironmentCallback> envCallbackWeak(envCallback_);
1064     NapiAsyncTask::CompleteCallback complete = [envCallbackWeak, callbackId, errCode](
1065             napi_env env, NapiAsyncTask &task, int32_t status) {
1066             if (errCode != 0) {
1067                 task.Reject(env, CreateJsError(env, errCode, "Invalidate params."));
1068                 return;
1069             }
1070             auto env_callback = envCallbackWeak.lock();
1071             if (env_callback == nullptr) {
1072                 TAG_LOGE(AAFwkTag::APPKIT, "env_callback is nullptr");
1073                 task.Reject(env, CreateJsError(env, ERROR_CODE_ONE, "env_callback is nullptr"));
1074                 return;
1075             }
1076 
1077             if (!env_callback->UnRegister(callbackId)) {
1078                 TAG_LOGE(AAFwkTag::APPKIT, "call UnRegister failed");
1079                 task.Reject(env, CreateJsError(env, ERROR_CODE_ONE, "call UnRegister failed!"));
1080                 return;
1081             }
1082 
1083             task.Resolve(env, CreateJsUndefined(env));
1084         };
1085     napi_value lastParam = (info.argc <= ARGC_ONE) ? nullptr : info.argv[INDEX_ONE];
1086     napi_value result = nullptr;
1087     NapiAsyncTask::Schedule("JsApplicationContextUtils::OnUnregisterEnvironmentCallback", env,
1088         CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1089     return result;
1090 }
1091 
On(napi_env env,napi_callback_info info)1092 napi_value JsApplicationContextUtils::On(napi_env env, napi_callback_info info)
1093 {
1094     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnOn, APPLICATION_CONTEXT_NAME);
1095 }
1096 
Off(napi_env env,napi_callback_info info)1097 napi_value JsApplicationContextUtils::Off(napi_env env, napi_callback_info info)
1098 {
1099     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnOff, APPLICATION_CONTEXT_NAME);
1100 }
1101 
OnOn(napi_env env,NapiCallbackInfo & info)1102 napi_value JsApplicationContextUtils::OnOn(napi_env env, NapiCallbackInfo& info)
1103 {
1104     TAG_LOGD(AAFwkTag::APPKIT, "called");
1105 
1106     if (info.argc != ARGC_TWO) {
1107         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
1108         ThrowInvalidParamError(env, "Not enough params.");
1109         return CreateJsUndefined(env);
1110     }
1111 
1112     if (!CheckTypeForNapiValue(env, info.argv[0], napi_string)) {
1113         TAG_LOGE(AAFwkTag::APPKIT, "param0 is invalid");
1114         ThrowInvalidParamError(env, "Parse param type failed, type must be string.");
1115         return CreateJsUndefined(env);
1116     }
1117     std::string type;
1118     if (!ConvertFromJsValue(env, info.argv[0], type)) {
1119         TAG_LOGE(AAFwkTag::APPKIT, "convert type failed");
1120         ThrowInvalidParamError(env,
1121             "Parse param type failed, type must be string.");
1122         return CreateJsUndefined(env);
1123     }
1124 
1125     if (type == "abilityLifecycle") {
1126         return OnOnAbilityLifecycle(env, info, false);
1127     }
1128     if (type == "abilityLifecycleEvent") {
1129         return OnOnAbilityLifecycle(env, info, true);
1130     }
1131     if (type == "environment") {
1132         return OnOnEnvironment(env, info, false);
1133     }
1134     if (type == "environmentEvent") {
1135         return OnOnEnvironment(env, info, true);
1136     }
1137     if (type == "applicationStateChange") {
1138         return OnOnApplicationStateChange(env, info);
1139     }
1140     TAG_LOGE(AAFwkTag::APPKIT, "on function type not match");
1141     ThrowInvalidParamError(env, "Parse param callback failed, callback must be function.");
1142     return CreateJsUndefined(env);
1143 }
1144 
OnOff(napi_env env,NapiCallbackInfo & info)1145 napi_value JsApplicationContextUtils::OnOff(napi_env env, NapiCallbackInfo& info)
1146 {
1147     TAG_LOGD(AAFwkTag::APPKIT, "called");
1148     if (info.argc < ARGC_ONE) {
1149         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
1150         ThrowInvalidParamError(env, "Not enough params.");
1151         return CreateJsUndefined(env);
1152     }
1153 
1154     if (!CheckTypeForNapiValue(env, info.argv[0], napi_string)) {
1155         TAG_LOGE(AAFwkTag::APPKIT, "param0 is invalid");
1156         ThrowInvalidParamError(env, "Parse param type failed, type must be string.");
1157         return CreateJsUndefined(env);
1158     }
1159     std::string type;
1160     if (!ConvertFromJsValue(env, info.argv[0], type)) {
1161         TAG_LOGE(AAFwkTag::APPKIT, "convert type failed");
1162         ThrowInvalidParamError(env,
1163             "Parse param type failed, type must be string.");
1164         return CreateJsUndefined(env);
1165     }
1166 
1167     if (type == "applicationStateChange") {
1168         return OnOffApplicationStateChange(env, info);
1169     }
1170 
1171     if (info.argc != ARGC_TWO && info.argc != ARGC_THREE) {
1172         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
1173         ThrowInvalidParamError(env, "Not enough params.");
1174         return CreateJsUndefined(env);
1175     }
1176 
1177     int32_t callbackId = -1;
1178     if (CheckTypeForNapiValue(env, info.argv[1], napi_number)) {
1179         napi_get_value_int32(env, info.argv[1], &callbackId);
1180         TAG_LOGD(AAFwkTag::APPKIT, "callbackId is %{public}d.", callbackId);
1181     }
1182 
1183     if (type == "abilityLifecycle") {
1184         return OnOffAbilityLifecycle(env, info, callbackId);
1185     }
1186     if (type == "abilityLifecycleEvent") {
1187         return OnOffAbilityLifecycleEventSync(env, info, callbackId);
1188     }
1189     if (type == "environment") {
1190         return OnOffEnvironment(env, info, callbackId);
1191     }
1192     if (type == "environmentEvent") {
1193         return OnOffEnvironmentEventSync(env, info, callbackId);
1194     }
1195     TAG_LOGE(AAFwkTag::APPKIT, "off function type not match.");
1196     ThrowInvalidParamError(env, "Parse param callback failed, callback must be function.");
1197     return CreateJsUndefined(env);
1198 }
1199 
OnOnAbilityLifecycle(napi_env env,NapiCallbackInfo & info,bool isSync)1200 napi_value JsApplicationContextUtils::OnOnAbilityLifecycle(
1201     napi_env env, NapiCallbackInfo& info, bool isSync)
1202 {
1203     auto applicationContext = applicationContext_.lock();
1204     if (applicationContext == nullptr) {
1205         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1206         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1207         return CreateJsUndefined(env);
1208     }
1209 
1210     if (callback_ != nullptr) {
1211         TAG_LOGD(AAFwkTag::APPKIT, "callback_ is not nullptr");
1212         return CreateJsValue(env, callback_->Register(info.argv[1], isSync));
1213     }
1214     callback_ = std::make_shared<JsAbilityLifecycleCallback>(env);
1215     int32_t callbackId = callback_->Register(info.argv[1], isSync);
1216     applicationContext->RegisterAbilityLifecycleCallback(callback_);
1217     return CreateJsValue(env, callbackId);
1218 }
1219 
OnOffAbilityLifecycle(napi_env env,NapiCallbackInfo & info,int32_t callbackId)1220 napi_value JsApplicationContextUtils::OnOffAbilityLifecycle(
1221     napi_env env, NapiCallbackInfo& info, int32_t callbackId)
1222 {
1223     auto applicationContext = applicationContext_.lock();
1224     if (applicationContext == nullptr) {
1225         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1226         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1227         return CreateJsUndefined(env);
1228     }
1229 
1230     std::weak_ptr<JsAbilityLifecycleCallback> callbackWeak(callback_);
1231     NapiAsyncTask::CompleteCallback complete = [callbackWeak, callbackId](
1232             napi_env env, NapiAsyncTask &task, int32_t status) {
1233             auto callback = callbackWeak.lock();
1234             if (callback == nullptr) {
1235                 TAG_LOGE(AAFwkTag::APPKIT, "callback is nullptr");
1236                 task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
1237                     "callback is nullptr"));
1238                 return;
1239             }
1240 
1241             if (!callback->UnRegister(callbackId, false)) {
1242                 TAG_LOGE(AAFwkTag::APPKIT, "call UnRegister failed");
1243                 task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
1244                     "call UnRegister failed!"));
1245                 return;
1246             }
1247 
1248             task.ResolveWithNoError(env, CreateJsUndefined(env));
1249         };
1250     napi_value lastParam = (info.argc <= ARGC_TWO) ? nullptr : info.argv[INDEX_TWO];
1251     napi_value result = nullptr;
1252     NapiAsyncTask::Schedule("JsApplicationContextUtils::OnOffAbilityLifecycle", env,
1253         CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1254     return result;
1255 }
1256 
OnOffAbilityLifecycleEventSync(napi_env env,NapiCallbackInfo & info,int32_t callbackId)1257 napi_value JsApplicationContextUtils::OnOffAbilityLifecycleEventSync(
1258     napi_env env, NapiCallbackInfo& info, int32_t callbackId)
1259 {
1260     TAG_LOGD(AAFwkTag::APPKIT, "called");
1261 
1262     auto applicationContext = applicationContext_.lock();
1263     if (applicationContext == nullptr) {
1264         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1265         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1266         return CreateJsUndefined(env);
1267     }
1268     if (callback_ == nullptr) {
1269         TAG_LOGE(AAFwkTag::APPKIT, "callback is nullptr");
1270         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1271         return CreateJsUndefined(env);
1272     }
1273     if (!callback_->UnRegister(callbackId, true)) {
1274         TAG_LOGE(AAFwkTag::APPKIT, "call UnRegister failed!");
1275         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1276         return CreateJsUndefined(env);
1277     }
1278     return CreateJsUndefined(env);
1279 }
1280 
OnOnEnvironment(napi_env env,NapiCallbackInfo & info,bool isSync)1281 napi_value JsApplicationContextUtils::OnOnEnvironment(
1282     napi_env env, NapiCallbackInfo& info, bool isSync)
1283 {
1284     TAG_LOGD(AAFwkTag::APPKIT, "called");
1285 
1286     auto applicationContext = applicationContext_.lock();
1287     if (applicationContext == nullptr) {
1288         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr.");
1289         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1290         return CreateJsUndefined(env);
1291     }
1292 
1293     if (envCallback_ != nullptr) {
1294         TAG_LOGD(AAFwkTag::APPKIT, "envCallback_ is not nullptr.");
1295         return CreateJsValue(env, envCallback_->Register(info.argv[1], isSync));
1296     }
1297     envCallback_ = std::make_shared<JsEnvironmentCallback>(env);
1298     int32_t callbackId = envCallback_->Register(info.argv[1], isSync);
1299     applicationContext->RegisterEnvironmentCallback(envCallback_);
1300     TAG_LOGD(AAFwkTag::APPKIT, "OnOnEnvironment is end");
1301     return CreateJsValue(env, callbackId);
1302 }
1303 
OnOffEnvironment(napi_env env,NapiCallbackInfo & info,int32_t callbackId)1304 napi_value JsApplicationContextUtils::OnOffEnvironment(
1305     napi_env env, NapiCallbackInfo& info, int32_t callbackId)
1306 {
1307     TAG_LOGD(AAFwkTag::APPKIT, "called");
1308 
1309     auto applicationContext = applicationContext_.lock();
1310     if (applicationContext == nullptr) {
1311         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1312         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1313         return CreateJsUndefined(env);
1314     }
1315 
1316     std::weak_ptr<JsEnvironmentCallback> envCallbackWeak(envCallback_);
1317     NapiAsyncTask::CompleteCallback complete = [envCallbackWeak, callbackId](
1318             napi_env env, NapiAsyncTask &task, int32_t status) {
1319             auto env_callback = envCallbackWeak.lock();
1320             if (env_callback == nullptr) {
1321                 TAG_LOGE(AAFwkTag::APPKIT, "env_callback is nullptr");
1322                 task.Reject(env,
1323                     CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
1324                         "env_callback is nullptr"));
1325                 return;
1326             }
1327 
1328             TAG_LOGD(AAFwkTag::APPKIT, "OnOffEnvironment begin");
1329             if (!env_callback->UnRegister(callbackId, false)) {
1330                 TAG_LOGE(AAFwkTag::APPKIT, "call UnRegister failed");
1331                 task.Reject(env, CreateJsError(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER,
1332                     "call UnRegister failed!"));
1333                 return;
1334             }
1335 
1336             task.ResolveWithNoError(env, CreateJsUndefined(env));
1337         };
1338     napi_value lastParam = (info.argc <= ARGC_TWO) ? nullptr : info.argv[INDEX_TWO];
1339     napi_value result = nullptr;
1340     NapiAsyncTask::Schedule("JsApplicationContextUtils::OnOffEnvironment", env,
1341         CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1342     return result;
1343 }
1344 
OnOffEnvironmentEventSync(napi_env env,NapiCallbackInfo & info,int32_t callbackId)1345 napi_value JsApplicationContextUtils::OnOffEnvironmentEventSync(
1346     napi_env env, NapiCallbackInfo& info, int32_t callbackId)
1347 {
1348     TAG_LOGD(AAFwkTag::APPKIT, "called");
1349 
1350     auto applicationContext = applicationContext_.lock();
1351     if (applicationContext == nullptr) {
1352         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1353         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1354         return CreateJsUndefined(env);
1355     }
1356     if (envCallback_ == nullptr) {
1357         TAG_LOGE(AAFwkTag::APPKIT, "env_callback is nullptr");
1358         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1359         return CreateJsUndefined(env);
1360     }
1361     if (!envCallback_->UnRegister(callbackId, true)) {
1362         TAG_LOGE(AAFwkTag::APPKIT, "call UnRegister failed");
1363         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1364         return CreateJsUndefined(env);
1365     }
1366     return CreateJsUndefined(env);
1367 }
1368 
OnOnApplicationStateChange(napi_env env,NapiCallbackInfo & info)1369 napi_value JsApplicationContextUtils::OnOnApplicationStateChange(
1370     napi_env env, NapiCallbackInfo& info)
1371 {
1372     TAG_LOGD(AAFwkTag::APPKIT, "called");
1373     auto applicationContext = applicationContext_.lock();
1374     if (applicationContext == nullptr) {
1375         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1376         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1377         return CreateJsUndefined(env);
1378     }
1379 
1380     std::lock_guard<std::mutex> lock(applicationStateCallbackLock_);
1381     if (applicationStateCallback_ != nullptr) {
1382         applicationStateCallback_->Register(info.argv[INDEX_ONE]);
1383         return CreateJsUndefined(env);
1384     }
1385 
1386     applicationStateCallback_ = std::make_shared<JsApplicationStateChangeCallback>(env);
1387     applicationStateCallback_->Register(info.argv[INDEX_ONE]);
1388     applicationContext->RegisterApplicationStateChangeCallback(applicationStateCallback_);
1389     return CreateJsUndefined(env);
1390 }
1391 
OnOffApplicationStateChange(napi_env env,NapiCallbackInfo & info)1392 napi_value JsApplicationContextUtils::OnOffApplicationStateChange(
1393     napi_env env, NapiCallbackInfo& info)
1394 {
1395     TAG_LOGD(AAFwkTag::APPKIT, "called");
1396     auto applicationContext = applicationContext_.lock();
1397     if (applicationContext == nullptr) {
1398         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationContext is nullptr");
1399         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1400         return CreateJsUndefined(env);
1401     }
1402 
1403     std::lock_guard<std::mutex> lock(applicationStateCallbackLock_);
1404     if (applicationStateCallback_ == nullptr) {
1405         TAG_LOGE(AAFwkTag::APPKIT, "ApplicationStateCallback_ is nullptr");
1406         ThrowInvalidParamError(env,
1407             "Parse applicationStateCallback failed, applicationStateCallback must be function.");
1408         return CreateJsUndefined(env);
1409     }
1410 
1411     if (info.argc == ARGC_ONE || !CheckTypeForNapiValue(env, info.argv[INDEX_ONE], napi_object)) {
1412         applicationStateCallback_->UnRegister();
1413     } else if (!applicationStateCallback_->UnRegister(info.argv[INDEX_ONE])) {
1414         TAG_LOGE(AAFwkTag::APPKIT, "call UnRegister failed");
1415         ThrowInvalidParamError(env, "Parse param call UnRegister failed, call UnRegister must be function.");
1416         return CreateJsUndefined(env);
1417     }
1418 
1419     if (applicationStateCallback_->IsEmpty()) {
1420         applicationStateCallback_.reset();
1421     }
1422     return CreateJsUndefined(env);
1423 }
1424 
GetApplicationContext(napi_env env,napi_callback_info info)1425 napi_value JsApplicationContextUtils::GetApplicationContext(napi_env env, napi_callback_info info)
1426 {
1427     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
1428         OnGetApplicationContext, APPLICATION_CONTEXT_NAME);
1429 }
1430 
OnGetApplicationContext(napi_env env,NapiCallbackInfo & info)1431 napi_value JsApplicationContextUtils::OnGetApplicationContext(napi_env env, NapiCallbackInfo& info)
1432 {
1433     TAG_LOGD(AAFwkTag::APPKIT, "called");
1434     auto applicationContext = applicationContext_.lock();
1435     if (!applicationContext) {
1436         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
1437         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1438         return CreateJsUndefined(env);
1439     }
1440 
1441     napi_value value = CreateJsApplicationContext(env);
1442     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.ApplicationContext", &value, 1);
1443     if (systemModule == nullptr) {
1444         TAG_LOGW(AAFwkTag::APPKIT, "invalid systemModule.");
1445         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1446         return CreateJsUndefined(env);
1447     }
1448     napi_value contextObj = systemModule->GetNapiValue();
1449     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
1450         TAG_LOGE(AAFwkTag::APPKIT, "Failed to get context native object");
1451         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
1452         return CreateJsUndefined(env);
1453     }
1454     auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(applicationContext);
1455     napi_coerce_to_native_binding_object(
1456         env, contextObj, DetachCallbackFunc, AttachApplicationContext, workContext, nullptr);
1457     if (workContext != nullptr) {
1458         auto res = napi_wrap(env, contextObj, workContext,
1459             [](napi_env, void *data, void *) {
1460               TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr application context is called");
1461               delete static_cast<std::weak_ptr<ApplicationContext> *>(data);
1462               data = nullptr;
1463             },
1464             nullptr, nullptr);
1465         if (res != napi_ok && workContext != nullptr) {
1466             TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
1467             delete workContext;
1468             return CreateJsUndefined(env);
1469         }
1470     }
1471     return contextObj;
1472 }
1473 
CheckCallerIsSystemApp()1474 bool JsApplicationContextUtils::CheckCallerIsSystemApp()
1475 {
1476     auto selfToken = IPCSkeleton::GetSelfTokenID();
1477     if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
1478         return false;
1479     }
1480     return true;
1481 }
1482 
CreateJsApplicationContext(napi_env env)1483 napi_value JsApplicationContextUtils::CreateJsApplicationContext(napi_env env)
1484 {
1485     TAG_LOGD(AAFwkTag::APPKIT, "start");
1486     napi_value object = nullptr;
1487     napi_create_object(env, &object);
1488     if (object == nullptr) {
1489         return nullptr;
1490     }
1491 
1492     std::shared_ptr<ApplicationContext> applicationContext = ApplicationContext::GetInstance();
1493     if (applicationContext == nullptr) {
1494         return object;
1495     }
1496 
1497     auto jsApplicationContextUtils = std::make_unique<JsApplicationContextUtils>(applicationContext);
1498     SetNamedNativePointer(env, object, APPLICATION_CONTEXT_NAME, jsApplicationContextUtils.release(),
1499         JsApplicationContextUtils::Finalizer);
1500 
1501     auto appInfo = applicationContext->GetApplicationInfo();
1502     if (appInfo != nullptr) {
1503         napi_set_named_property(env, object, "applicationInfo", CreateJsApplicationInfo(env, *appInfo));
1504     }
1505     auto resourceManager = applicationContext->GetResourceManager();
1506     std::shared_ptr<Context> context = std::dynamic_pointer_cast<Context>(applicationContext);
1507     if (resourceManager != nullptr) {
1508         napi_set_named_property(env, object, "resourceManager", CreateJsResourceManager(env, resourceManager, context));
1509     }
1510 
1511     BindNativeApplicationContext(env, object);
1512     return object;
1513 }
1514 
SetSupportedProcessCacheSelf(napi_env env,napi_callback_info info)1515 napi_value JsApplicationContextUtils::SetSupportedProcessCacheSelf(napi_env env, napi_callback_info info)
1516 {
1517     GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils,
1518         OnSetSupportedProcessCacheSelf, APPLICATION_CONTEXT_NAME);
1519 }
1520 
OnSetSupportedProcessCacheSelf(napi_env env,NapiCallbackInfo & info)1521 napi_value JsApplicationContextUtils::OnSetSupportedProcessCacheSelf(napi_env env, NapiCallbackInfo& info)
1522 {
1523     TAG_LOGD(AAFwkTag::APPKIT, "called");
1524 
1525     // only support one params
1526     if (info.argc == ARGC_ZERO) {
1527         TAG_LOGE(AAFwkTag::APPKIT, "Not enough params");
1528         ThrowInvalidParamError(env, "Not enough params.");
1529         return CreateJsUndefined(env);
1530     }
1531     auto applicationContext = applicationContext_.lock();
1532     if (applicationContext == nullptr) {
1533         TAG_LOGW(AAFwkTag::APPKIT, "applicationContext is already released");
1534         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_CONTEXT_NOT_EXIST);
1535         return CreateJsUndefined(env);
1536     }
1537 
1538     bool isSupport = false;
1539     if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], isSupport)) {
1540         TAG_LOGE(AAFwkTag::APPKIT, "Parse isSupport failed");
1541         ThrowInvalidParamError(env,
1542             "Parse param isSupport failed, isSupport must be boolean.");
1543         return CreateJsUndefined(env);
1544     }
1545 
1546     int32_t errCode = applicationContext->SetSupportedProcessCacheSelf(isSupport);
1547     if (errCode == AAFwk::ERR_CAPABILITY_NOT_SUPPORT) {
1548         TAG_LOGE(AAFwkTag::APPKIT, "process cache feature is disabled.");
1549         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_NO_SUCH_SYSCAP);
1550     } else if (errCode != ERR_OK) {
1551         TAG_LOGE(AAFwkTag::APPKIT, "set failed");
1552         AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
1553     }
1554     return CreateJsUndefined(env);
1555 }
1556 
BindNativeApplicationContext(napi_env env,napi_value object)1557 void JsApplicationContextUtils::BindNativeApplicationContext(napi_env env, napi_value object)
1558 {
1559     BindNativeProperty(env, object, "cacheDir", JsApplicationContextUtils::GetCacheDir);
1560     BindNativeProperty(env, object, "tempDir", JsApplicationContextUtils::GetTempDir);
1561     BindNativeProperty(env, object, "resourceDir", JsApplicationContextUtils::GetResourceDir);
1562     BindNativeProperty(env, object, "filesDir", JsApplicationContextUtils::GetFilesDir);
1563     BindNativeProperty(env, object, "distributedFilesDir", JsApplicationContextUtils::GetDistributedFilesDir);
1564     BindNativeProperty(env, object, "databaseDir", JsApplicationContextUtils::GetDatabaseDir);
1565     BindNativeProperty(env, object, "preferencesDir", JsApplicationContextUtils::GetPreferencesDir);
1566     BindNativeProperty(env, object, "bundleCodeDir", JsApplicationContextUtils::GetBundleCodeDir);
1567     BindNativeProperty(env, object, "cloudFileDir", JsApplicationContextUtils::GetCloudFileDir);
1568     BindNativeFunction(env, object, "registerAbilityLifecycleCallback", MD_NAME,
1569         JsApplicationContextUtils::RegisterAbilityLifecycleCallback);
1570     BindNativeFunction(env, object, "unregisterAbilityLifecycleCallback", MD_NAME,
1571         JsApplicationContextUtils::UnregisterAbilityLifecycleCallback);
1572     BindNativeFunction(env, object, "registerEnvironmentCallback", MD_NAME,
1573         JsApplicationContextUtils::RegisterEnvironmentCallback);
1574     BindNativeFunction(env, object, "unregisterEnvironmentCallback", MD_NAME,
1575         JsApplicationContextUtils::UnregisterEnvironmentCallback);
1576     BindNativeFunction(env, object, "createBundleContext", MD_NAME, JsApplicationContextUtils::CreateBundleContext);
1577     BindNativeFunction(env, object, "switchArea", MD_NAME, JsApplicationContextUtils::SwitchArea);
1578     BindNativeFunction(env, object, "getArea", MD_NAME, JsApplicationContextUtils::GetArea);
1579     BindNativeFunction(env, object, "createModuleContext", MD_NAME, JsApplicationContextUtils::CreateModuleContext);
1580     BindNativeFunction(env, object, "createSystemHspModuleResourceManager", MD_NAME,
1581         JsApplicationContextUtils::CreateSystemHspModuleResourceManager);
1582     BindNativeFunction(env, object, "createModuleResourceManager", MD_NAME,
1583         JsApplicationContextUtils::CreateModuleResourceManager);
1584     BindNativeFunction(env, object, "on", MD_NAME, JsApplicationContextUtils::On);
1585     BindNativeFunction(env, object, "off", MD_NAME, JsApplicationContextUtils::Off);
1586     BindNativeFunction(env, object, "getApplicationContext", MD_NAME,
1587         JsApplicationContextUtils::GetApplicationContext);
1588     BindNativeFunction(env, object, "killAllProcesses", MD_NAME, JsApplicationContextUtils::KillProcessBySelf);
1589     BindNativeFunction(env, object, "setColorMode", MD_NAME, JsApplicationContextUtils::SetColorMode);
1590     BindNativeFunction(env, object, "setLanguage", MD_NAME, JsApplicationContextUtils::SetLanguage);
1591     BindNativeFunction(env, object, "setFont", MD_NAME, JsApplicationContextUtils::SetFont);
1592     BindNativeFunction(env, object, "clearUpApplicationData", MD_NAME,
1593         JsApplicationContextUtils::ClearUpApplicationData);
1594     BindNativeFunction(env, object, "preloadUIExtensionAbility", MD_NAME,
1595         JsApplicationContextUtils::PreloadUIExtensionAbility);
1596     BindNativeFunction(env, object, "getProcessRunningInformation", MD_NAME,
1597         JsApplicationContextUtils::GetRunningProcessInformation);
1598     BindNativeFunction(env, object, "getRunningProcessInformation", MD_NAME,
1599         JsApplicationContextUtils::GetRunningProcessInformation);
1600     BindNativeFunction(env, object, "getCurrentAppCloneIndex", MD_NAME,
1601         JsApplicationContextUtils::GetCurrentAppCloneIndex);
1602     BindNativeFunction(env, object, "getGroupDir", MD_NAME, JsApplicationContextUtils::GetGroupDir);
1603     BindNativeFunction(env, object, "restartApp", MD_NAME, JsApplicationContextUtils::RestartApp);
1604     BindNativeFunction(env, object, "setSupportedProcessCache", MD_NAME,
1605         JsApplicationContextUtils::SetSupportedProcessCacheSelf);
1606     BindNativeFunction(env, object, "setFontSizeScale", MD_NAME,
1607         JsApplicationContextUtils::SetFontSizeScale);
1608 }
1609 
ConvertToJsAppProcessState(const AppExecFwk::AppProcessState & appProcessState,const bool & isFocused)1610 JsAppProcessState JsApplicationContextUtils::ConvertToJsAppProcessState(
1611     const AppExecFwk::AppProcessState &appProcessState, const bool &isFocused)
1612 {
1613     JsAppProcessState processState;
1614     switch (appProcessState) {
1615         case AppExecFwk::AppProcessState::APP_STATE_CREATE:
1616         case AppExecFwk::AppProcessState::APP_STATE_READY:
1617             processState = STATE_CREATE;
1618             break;
1619         case AppExecFwk::AppProcessState::APP_STATE_FOREGROUND:
1620             processState = isFocused ? STATE_ACTIVE : STATE_FOREGROUND;
1621             break;
1622         case AppExecFwk::AppProcessState::APP_STATE_BACKGROUND:
1623             processState = STATE_BACKGROUND;
1624             break;
1625         case AppExecFwk::AppProcessState::APP_STATE_TERMINATED:
1626         case AppExecFwk::AppProcessState::APP_STATE_END:
1627             processState = STATE_DESTROY;
1628             break;
1629         default:
1630             TAG_LOGE(AAFwkTag::APPKIT, "Process state is invalid.");
1631             processState = STATE_DESTROY;
1632             break;
1633     }
1634     return processState;
1635 }
1636 }  // namespace AbilityRuntime
1637 }  // namespace OHOS
1638