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