1 /*
2 * Copyright (c) 2025 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 #include "ets_application_context_utils.h"
16
17 #include "ani_enum_convert.h"
18 #include "application_context_manager.h"
19 #include "ets_context_utils.h"
20 #include "ets_error_utils.h"
21 #include "ets_native_reference.h"
22 #include "hilog_tag_wrapper.h"
23
24 namespace OHOS {
25 namespace AbilityRuntime {
26 namespace {
27 static std::once_flag g_bindNativeMethodsFlag;
28 constexpr const char* ETS_APPLICATION_CONTEXT_CLASS_NAME = "Lapplication/ApplicationContext/ApplicationContext;";
29 constexpr const char* CLEANER_CLASS = "Lapplication/ApplicationContext/Cleaner;";
30 constexpr double FOUNT_SIZE = 0.0;
31 }
Clean(ani_env * env,ani_object object)32 void EtsApplicationContextUtils::Clean(ani_env *env, ani_object object)
33 {
34 TAG_LOGD(AAFwkTag::APPKIT, "Clean Call");
35 if (env == nullptr) {
36 TAG_LOGE(AAFwkTag::APPKIT, "null env");
37 return;
38 }
39 ani_long ptr = 0;
40 ani_status status = env->Object_GetFieldByName_Long(object, "ptr", &ptr);
41 if (status != ANI_OK) {
42 TAG_LOGE(AAFwkTag::APPKIT, "ptr GetField status: %{public}d", status);
43 return;
44 }
45 if (ptr != 0) {
46 delete reinterpret_cast<EtsApplicationContextUtils *>(ptr);
47 }
48 }
49
OnRestartApp(ani_env * env,ani_object aniObj,ani_object wantObj)50 void EtsApplicationContextUtils::OnRestartApp(ani_env *env, ani_object aniObj, ani_object wantObj)
51 {
52 if (env == nullptr) {
53 TAG_LOGE(AAFwkTag::APPKIT, "null env");
54 return;
55 }
56 auto applicationContext = applicationContext_.lock();
57 if (applicationContext == nullptr) {
58 TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext");
59 return;
60 }
61 AAFwk::Want want;
62 if (!AppExecFwk::UnwrapWant(env, wantObj, want)) {
63 TAG_LOGE(AAFwkTag::APPKIT, "Parse want failed");
64 EtsErrorUtil::ThrowInvalidParamError(env, "Parse param want failed, want must be Want.");
65 return;
66 }
67 auto errCode = applicationContext->RestartApp(want);
68 switch (errCode) {
69 case ERR_INVALID_VALUE:
70 EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
71 break;
72 case AAFwk::ERR_RESTART_APP_INCORRECT_ABILITY:
73 EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_RESTART_APP_INCORRECT_ABILITY);
74 break;
75 case AAFwk::ERR_RESTART_APP_FREQUENT:
76 EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_RESTART_APP_FREQUENT);
77 break;
78 case AAFwk::NOT_TOP_ABILITY:
79 EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_NOT_TOP_ABILITY);
80 break;
81 default:
82 EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
83 }
84 TAG_LOGD(AAFwkTag::APPKIT, "RestartApp errCode is %{public}d", errCode);
85 }
86
OnSetFont(ani_env * env,ani_object aniObj,ani_string font)87 void EtsApplicationContextUtils::OnSetFont(ani_env *env, ani_object aniObj, ani_string font)
88 {
89 if (env == nullptr) {
90 TAG_LOGE(AAFwkTag::APPKIT, "null env");
91 return;
92 }
93 auto applicationContext = applicationContext_.lock();
94 if (applicationContext == nullptr) {
95 TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext");
96 return;
97 }
98 std::string stdFont = "";
99 if (!AppExecFwk::GetStdString(env, font, stdFont) || stdFont.empty()) {
100 TAG_LOGE(AAFwkTag::APPKIT, "Parse font failed");
101 EtsErrorUtil::ThrowInvalidParamError(env, "Parse param font failed, font must be string.");
102 return;
103 }
104 TAG_LOGD(AAFwkTag::APPKIT, "SetFont font %{public}s", stdFont.c_str());
105 applicationContext->SetFont(stdFont);
106 }
107
OnSetColorMode(ani_env * env,ani_object aniObj,ani_enum_item colorMode)108 void EtsApplicationContextUtils::OnSetColorMode(ani_env *env, ani_object aniObj, ani_enum_item colorMode)
109 {
110 if (env == nullptr) {
111 TAG_LOGE(AAFwkTag::APPKIT, "null env");
112 return;
113 }
114 auto applicationContext = applicationContext_.lock();
115 if (applicationContext == nullptr) {
116 TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext");
117 return;
118 }
119 ani_int mode = 0;
120 if (!AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(env, colorMode, mode)) {
121 EtsErrorUtil::ThrowInvalidParamError(env, "Parse param colorMode failed, colorMode must be number.");
122 TAG_LOGE(AAFwkTag::APPKIT, "Parse colorMode failed");
123 return;
124 }
125 TAG_LOGD(AAFwkTag::APPKIT, "colorMode is %{public}d", mode);
126 applicationContext->SetColorMode(static_cast<int32_t>(mode));
127 }
128
OnSetLanguage(ani_env * env,ani_object aniObj,ani_string language)129 void EtsApplicationContextUtils::OnSetLanguage(ani_env *env, ani_object aniObj, ani_string language)
130 {
131 if (env == nullptr) {
132 TAG_LOGE(AAFwkTag::APPKIT, "null env");
133 return;
134 }
135 auto applicationContext = applicationContext_.lock();
136 if (applicationContext == nullptr) {
137 TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext");
138 return;
139 }
140 std::string stdLanguage = "";
141 if (!AppExecFwk::GetStdString(env, language, stdLanguage) || stdLanguage.empty()) {
142 TAG_LOGE(AAFwkTag::APPKIT, "Parse language failed");
143 EtsErrorUtil::ThrowInvalidParamError(env, "Parse param language failed, language must be string.");
144 return;
145 }
146 applicationContext->SetLanguage(stdLanguage);
147 TAG_LOGD(AAFwkTag::APPKIT, "stdLanguage language %{public}s", stdLanguage.c_str());
148 }
149
OnSetFontSizeScale(ani_env * env,ani_object aniObj,ani_double fontSizeScale)150 void EtsApplicationContextUtils::OnSetFontSizeScale(ani_env *env, ani_object aniObj, ani_double fontSizeScale)
151 {
152 if (env == nullptr) {
153 TAG_LOGE(AAFwkTag::APPKIT, "null env");
154 return;
155 }
156 auto applicationContext = applicationContext_.lock();
157 if (applicationContext == nullptr) {
158 TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext");
159 return;
160 }
161
162 double stdFontSizeScale = static_cast<double>(fontSizeScale);
163 TAG_LOGD(AAFwkTag::APPKIT, "fontSizeScale: %{public}f", stdFontSizeScale);
164 if (fontSizeScale < FOUNT_SIZE) {
165 TAG_LOGE(AAFwkTag::APPKIT, "invalid size");
166 EtsErrorUtil::ThrowInvalidParamError(env, "Invalid font size.");
167 return;
168 }
169 applicationContext->SetFontSizeScale(stdFontSizeScale);
170 }
171
OnClearUpApplicationData(ani_env * env,ani_object aniObj,ani_object callback)172 void EtsApplicationContextUtils::OnClearUpApplicationData(ani_env *env, ani_object aniObj, ani_object callback)
173 {
174 if (env == nullptr) {
175 TAG_LOGE(AAFwkTag::APPKIT, "null env");
176 return;
177 }
178 auto applicationContext = applicationContext_.lock();
179 if (applicationContext == nullptr) {
180 TAG_LOGE(AAFwkTag::APPKIT, "nativeContext is null");
181 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateError(env,
182 (ani_int)AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT,
183 "applicationContext if already released."), nullptr);
184 return;
185 }
186 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_OK), nullptr);
187 applicationContext->ClearUpApplicationData();
188 }
189
OnGetRunningProcessInformation(ani_env * env,ani_object aniObj,ani_object callback)190 void EtsApplicationContextUtils::OnGetRunningProcessInformation(ani_env *env, ani_object aniObj, ani_object callback)
191 {
192 if (env == nullptr) {
193 TAG_LOGE(AAFwkTag::APPKIT, "null env");
194 return;
195 }
196 ani_object emptyArray = AppExecFwk::CreateEmptyArray(env);
197 auto applicationContext = applicationContext_.lock();
198 if (applicationContext == nullptr) {
199 TAG_LOGE(AAFwkTag::APPKIT, "nativeContext is null");
200 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateError(env,
201 (ani_int)AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT,
202 "applicationContext if already released."), emptyArray);
203 return;
204 }
205 std::vector<AppExecFwk::RunningProcessInfo> infos;
206 AppExecFwk::RunningProcessInfo processInfo;
207 ErrCode innerErrCode = applicationContext->GetProcessRunningInformation(processInfo);
208 if (innerErrCode == ERR_OK) {
209 infos.emplace_back(processInfo);
210 ani_object aniInfosRef = AppExecFwk::CreateRunningProcessInfoArray(env, infos);
211 if (aniInfosRef == nullptr) {
212 TAG_LOGE(AAFwkTag::APPKIT, "null array");
213 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateError(env,
214 (ani_int)AbilityErrorCode::ERROR_CODE_INNER, "Initiate array failed."), emptyArray);
215 } else {
216 AppExecFwk::AsyncCallback(env, callback,
217 EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_OK), aniInfosRef);
218 }
219 } else {
220 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateError(env,
221 (ani_int)AbilityErrorCode::ERROR_CODE_INNER, "Get process infos failed."), emptyArray);
222 }
223 }
224
OnkillAllProcesses(ani_env * env,ani_object aniObj,ani_boolean clearPageStack,ani_object callback)225 void EtsApplicationContextUtils::OnkillAllProcesses(ani_env *env, ani_object aniObj,
226 ani_boolean clearPageStack, ani_object callback)
227 {
228 if (env == nullptr) {
229 TAG_LOGE(AAFwkTag::APPKIT, "env is nullptr");
230 return;
231 }
232 ani_object aniObject = EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_OK);
233 auto context = applicationContext_.lock();
234 if (!context) {
235 TAG_LOGE(AAFwkTag::APPKIT, "nativeContextLong is nullptr");
236 aniObject = EtsErrorUtil::CreateError(env, (ani_int)AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT,
237 "applicationContext is already released.");
238 AppExecFwk::AsyncCallback(env, callback, aniObject, nullptr);
239 return;
240 }
241 AppExecFwk::AsyncCallback(env, callback, aniObject, nullptr);
242 context->KillProcessBySelf(clearPageStack);
243 }
244
OnPreloadUIExtensionAbility(ani_env * env,ani_object aniObj,ani_object wantObj,ani_object callback)245 void EtsApplicationContextUtils::OnPreloadUIExtensionAbility(ani_env *env,
246 ani_object aniObj, ani_object wantObj, ani_object callback)
247 {
248 TAG_LOGD(AAFwkTag::APPKIT, "PreloadUIExtensionAbility Call");
249 if (env == nullptr) {
250 TAG_LOGE(AAFwkTag::APPKIT, "null env");
251 return;
252 }
253 AAFwk::Want want;
254 if (!OHOS::AppExecFwk::UnwrapWant(env, wantObj, want)) {
255 TAG_LOGE(AAFwkTag::APPKIT, "Parse want failed");
256 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateInvalidParamError(env,
257 "Parse param want failed, want must be Want."), nullptr);
258 return;
259 }
260 auto context = applicationContext_.lock();
261 if (!context) {
262 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateErrorByNativeErr(env,
263 (int32_t)AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT), nullptr);
264 return;
265 }
266 auto hostBundleName = context->GetBundleName();
267 TAG_LOGD(AAFwkTag::APPKIT, "HostBundleName is %{public}s", hostBundleName.c_str());
268 auto innerErrCode = AAFwk::AbilityManagerClient::GetInstance()->PreloadUIExtensionAbility(want, hostBundleName);
269 if (innerErrCode == ERR_OK) {
270 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateError(env,
271 AbilityErrorCode::ERROR_OK), nullptr);
272 } else {
273 TAG_LOGE(AAFwkTag::APPKIT, "OnPreloadUIExtensionAbility failed %{public}d", innerErrCode);
274 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateErrorByNativeErr(env, innerErrCode), nullptr);
275 }
276 }
277
OnSetSupportedProcessCacheSync(ani_env * env,ani_object aniObj,ani_boolean value)278 void EtsApplicationContextUtils::OnSetSupportedProcessCacheSync(ani_env *env, ani_object aniObj, ani_boolean value)
279 {
280 if (env == nullptr) {
281 TAG_LOGE(AAFwkTag::APPKIT, "null env");
282 return;
283 }
284 auto applicationContext = applicationContext_.lock();
285 if (applicationContext == nullptr) {
286 TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext");
287 EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
288 return;
289 }
290 int32_t errCode = applicationContext->SetSupportedProcessCacheSelf(value);
291 if (errCode == AAFwk::ERR_CAPABILITY_NOT_SUPPORT) {
292 EtsErrorUtil::ThrowError(env,
293 AbilityErrorCode::ERROR_CODE_CAPABILITY_NOT_SUPPORT);
294 } else if (errCode != ERR_OK) {
295 EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
296 }
297 }
298
RestartApp(ani_env * env,ani_object aniObj,ani_object wantObj)299 void EtsApplicationContextUtils::RestartApp(ani_env *env, ani_object aniObj, ani_object wantObj)
300 {
301 TAG_LOGD(AAFwkTag::APPKIT, "RestartApp Call");
302 auto etsContext = GeApplicationContext(env, aniObj);
303 if (etsContext == nullptr) {
304 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
305 return;
306 }
307 etsContext->OnRestartApp(env, aniObj, wantObj);
308 }
309
SetFont(ani_env * env,ani_object aniObj,ani_string font)310 void EtsApplicationContextUtils::SetFont(ani_env *env, ani_object aniObj, ani_string font)
311 {
312 TAG_LOGD(AAFwkTag::APPKIT, "SetFont Call");
313 auto etsContext = GeApplicationContext(env, aniObj);
314 if (etsContext == nullptr) {
315 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
316 return;
317 }
318 etsContext->OnSetFont(env, aniObj, font);
319 }
320
SetColorMode(ani_env * env,ani_object aniObj,ani_enum_item colorMode)321 void EtsApplicationContextUtils::SetColorMode(ani_env *env, ani_object aniObj, ani_enum_item colorMode)
322 {
323 TAG_LOGD(AAFwkTag::APPKIT, "SetColorMode Call");
324 auto etsContext = GeApplicationContext(env, aniObj);
325 if (etsContext == nullptr) {
326 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
327 return;
328 }
329 etsContext->OnSetColorMode(env, aniObj, colorMode);
330 }
331
SetLanguage(ani_env * env,ani_object aniObj,ani_string language)332 void EtsApplicationContextUtils::SetLanguage(ani_env *env, ani_object aniObj, ani_string language)
333 {
334 TAG_LOGD(AAFwkTag::APPKIT, "SetLanguage Call");
335 auto etsContext = GeApplicationContext(env, aniObj);
336 if (etsContext == nullptr) {
337 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
338 return;
339 }
340 etsContext->OnSetLanguage(env, aniObj, language);
341 }
342
SetFontSizeScale(ani_env * env,ani_object aniObj,ani_double fontSizeScale)343 void EtsApplicationContextUtils::SetFontSizeScale(ani_env *env, ani_object aniObj, ani_double fontSizeScale)
344 {
345 TAG_LOGD(AAFwkTag::APPKIT, "SetFontSizeScale Call");
346 auto etsContext = GeApplicationContext(env, aniObj);
347 if (etsContext == nullptr) {
348 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
349 return;
350 }
351 etsContext->OnSetFontSizeScale(env, aniObj, fontSizeScale);
352 }
353
ClearUpApplicationData(ani_env * env,ani_object aniObj,ani_object callback)354 void EtsApplicationContextUtils::ClearUpApplicationData(ani_env *env, ani_object aniObj, ani_object callback)
355 {
356 TAG_LOGD(AAFwkTag::APPKIT, "ClearUpApplicationData Call");
357 auto etsContext = GeApplicationContext(env, aniObj);
358 if (etsContext == nullptr) {
359 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
360 return;
361 }
362 etsContext->OnClearUpApplicationData(env, aniObj, callback);
363 }
364
GetRunningProcessInformation(ani_env * env,ani_object aniObj,ani_object callback)365 void EtsApplicationContextUtils::GetRunningProcessInformation(ani_env *env, ani_object aniObj, ani_object callback)
366 {
367 TAG_LOGD(AAFwkTag::APPKIT, "GetRunningProcessInformation Call");
368 auto etsContext = GeApplicationContext(env, aniObj);
369 if (etsContext == nullptr) {
370 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
371 return;
372 }
373 etsContext->OnGetRunningProcessInformation(env, aniObj, callback);
374 }
375
killAllProcesses(ani_env * env,ani_object aniObj,ani_boolean clearPageStack,ani_object callback)376 void EtsApplicationContextUtils::killAllProcesses(ani_env *env, ani_object aniObj,
377 ani_boolean clearPageStack, ani_object callback)
378 {
379 TAG_LOGD(AAFwkTag::APPKIT, "killAllProcesses Call");
380 auto etsContext = GeApplicationContext(env, aniObj);
381 if (etsContext == nullptr) {
382 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
383 return;
384 }
385 etsContext->OnkillAllProcesses(env, aniObj, clearPageStack, callback);
386 }
387
PreloadUIExtensionAbility(ani_env * env,ani_object aniObj,ani_object wantObj,ani_object callback)388 void EtsApplicationContextUtils::PreloadUIExtensionAbility(ani_env *env,
389 ani_object aniObj, ani_object wantObj, ani_object callback)
390 {
391 TAG_LOGD(AAFwkTag::APPKIT, "PreloadUIExtensionAbility Call");
392 auto etsContext = GeApplicationContext(env, aniObj);
393 if (etsContext == nullptr) {
394 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
395 return;
396 }
397 etsContext->OnPreloadUIExtensionAbility(env, aniObj, wantObj, callback);
398 }
399
SetSupportedProcessCacheSync(ani_env * env,ani_object aniObj,ani_boolean value)400 void EtsApplicationContextUtils::SetSupportedProcessCacheSync(ani_env *env, ani_object aniObj, ani_boolean value)
401 {
402 TAG_LOGD(AAFwkTag::APPKIT, "SetSupportedProcessCacheSync Call");
403 auto etsContext = GeApplicationContext(env, aniObj);
404 if (etsContext == nullptr) {
405 TAG_LOGE(AAFwkTag::APPKIT, "null etsContext");
406 return;
407 }
408 etsContext->OnSetSupportedProcessCacheSync(env, aniObj, value);
409 }
410
GeApplicationContext(ani_env * env,ani_object aniObj)411 EtsApplicationContextUtils* EtsApplicationContextUtils::GeApplicationContext(ani_env *env, ani_object aniObj)
412 {
413 if (env == nullptr || aniObj == nullptr) {
414 TAG_LOGE(AAFwkTag::APPKIT, "null env or aniObj");
415 return nullptr;
416 }
417 ani_long etsApplicationContextPtr = 0;
418 ani_status status = env->Object_GetFieldByName_Long(aniObj, "etsApplicationContextPtr", &etsApplicationContextPtr);
419 if (status != ANI_OK) {
420 TAG_LOGE(AAFwkTag::APPKIT, "etsApplicationContextPtr GetField status: %{public}d", status);
421 return nullptr;
422 }
423 auto etsContext = reinterpret_cast<EtsApplicationContextUtils *>(etsApplicationContextPtr);
424 return etsContext;
425 }
426
SetApplicationContext(ani_env * aniEnv,const std::shared_ptr<ApplicationContext> & applicationContext)427 ani_object EtsApplicationContextUtils::SetApplicationContext(ani_env* aniEnv,
428 const std::shared_ptr<ApplicationContext> &applicationContext)
429 {
430 TAG_LOGD(AAFwkTag::APPKIT, "SetApplicationContext Call");
431 if (aniEnv == nullptr) {
432 TAG_LOGE(AAFwkTag::APPKIT, "null aniEnv");
433 return nullptr;
434 }
435 if (applicationContext == nullptr) {
436 TAG_LOGE(AAFwkTag::APPKIT, "null context");
437 return nullptr;
438 }
439 ani_status status = ANI_ERROR;
440 ani_class cls {};
441 if ((status = aniEnv->FindClass(ETS_APPLICATION_CONTEXT_CLASS_NAME, &cls)) != ANI_OK) {
442 TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status);
443 return nullptr;
444 }
445 ani_method method {};
446 if ((status = aniEnv->Class_FindMethod(cls, "<ctor>", "J:V", &method)) != ANI_OK) {
447 TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status);
448 return nullptr;
449 }
450 auto etsContext = new (std::nothrow) EtsApplicationContextUtils(applicationContext);
451 if (etsContext == nullptr) {
452 TAG_LOGE(AAFwkTag::APPKIT, "workContext nullptr");
453 return nullptr;
454 }
455 ani_object contextObj = nullptr;
456 if ((status = aniEnv->Object_New(cls, method, &contextObj, reinterpret_cast<ani_long>(etsContext))) != ANI_OK) {
457 TAG_LOGE(AAFwkTag::APPKIT, "status: %{public}d", status);
458 delete etsContext;
459 etsContext = nullptr;
460 return nullptr;
461 }
462 auto workContext = new (std::nothrow) std::weak_ptr<ApplicationContext>(etsContext->applicationContext_);
463 if (workContext == nullptr) {
464 TAG_LOGE(AAFwkTag::CONTEXT, "null workContext");
465 return nullptr;
466 }
467 ani_long nativeContextLong = reinterpret_cast<ani_long>(workContext);
468 if (!ContextUtil::SetNativeContextLong(aniEnv, contextObj, nativeContextLong)) {
469 TAG_LOGE(AAFwkTag::APPKIT, "SetNativeContextLong failed");
470 delete workContext;
471 workContext = nullptr;
472 return nullptr;
473 }
474 return contextObj;
475 }
476
BindApplicationContextFunc(ani_env * aniEnv)477 void EtsApplicationContextUtils::BindApplicationContextFunc(ani_env* aniEnv)
478 {
479 if (aniEnv == nullptr) {
480 TAG_LOGE(AAFwkTag::APPKIT, "null aniEnv");
481 return;
482 }
483 ani_class contextClass = nullptr;
484 ani_status status = ANI_ERROR;
485 if ((status = aniEnv->FindClass(ETS_APPLICATION_CONTEXT_CLASS_NAME, &contextClass)) != ANI_OK) {
486 TAG_LOGE(AAFwkTag::APPKIT, "FindClass ApplicationContext failed status: %{public}d", status);
487 return;
488 }
489 std::call_once(g_bindNativeMethodsFlag, [&status, aniEnv, contextClass]() {
490 std::array applicationContextFunctions = {
491 ani_native_function {"setSupportedProcessCacheSync", "Z:V",
492 reinterpret_cast<void *>(EtsApplicationContextUtils::SetSupportedProcessCacheSync)},
493 ani_native_function {"nativekillAllProcessesSync", "ZLutils/AbilityUtils/AsyncCallbackWrapper;:V",
494 reinterpret_cast<void *>(EtsApplicationContextUtils::killAllProcesses)},
495 ani_native_function {"nativepreloadUIExtensionAbilitySync",
496 "L@ohos/app/ability/Want/Want;Lutils/AbilityUtils/AsyncCallbackWrapper;:V",
497 reinterpret_cast<void *>(EtsApplicationContextUtils::PreloadUIExtensionAbility)},
498 ani_native_function {"nativegetRunningProcessInformation",
499 "Lutils/AbilityUtils/AsyncCallbackWrapper;:V",
500 reinterpret_cast<void *>(EtsApplicationContextUtils::GetRunningProcessInformation)},
501 ani_native_function {"nativeclearUpApplicationData",
502 "Lutils/AbilityUtils/AsyncCallbackWrapper;:V",
503 reinterpret_cast<void *>(EtsApplicationContextUtils::ClearUpApplicationData)},
504 ani_native_function {"nativesetLanguage", "Lstd/core/String;:V",
505 reinterpret_cast<void *>(EtsApplicationContextUtils::SetLanguage)},
506 ani_native_function {"nativesetFontSizeScale", "D:V",
507 reinterpret_cast<void *>(EtsApplicationContextUtils::SetFontSizeScale)},
508 ani_native_function {"nativesetColorMode",
509 "L@ohos/app/ability/ConfigurationConstant/ConfigurationConstant/ColorMode;:V",
510 reinterpret_cast<void *>(EtsApplicationContextUtils::SetColorMode)},
511 ani_native_function {"nativesetFont", "Lstd/core/String;:V",
512 reinterpret_cast<void *>(EtsApplicationContextUtils::SetFont)},
513 ani_native_function {"nativerestartApp", "L@ohos/app/ability/Want/Want;:V",
514 reinterpret_cast<void *>(EtsApplicationContextUtils::RestartApp)},
515 };
516 if ((status = aniEnv->Class_BindNativeMethods(contextClass, applicationContextFunctions.data(),
517 applicationContextFunctions.size())) != ANI_OK) {
518 TAG_LOGE(AAFwkTag::APPKIT, "Class_BindNativeMethods failed status: %{public}d", status);
519 return;
520 }
521 ani_class cleanerCls = nullptr;
522 if ((status = aniEnv->FindClass(CLEANER_CLASS, &cleanerCls)) != ANI_OK || cleanerCls == nullptr) {
523 TAG_LOGE(AAFwkTag::APPKIT, "Cleaner FindClass failed status: %{public}d, or null cleanerCls", status);
524 return;
525 }
526 std::array cleanerMethods = {
527 ani_native_function {"clean", nullptr, reinterpret_cast<void *>(EtsApplicationContextUtils::Clean) },
528 };
529 if ((status = aniEnv->Class_BindNativeMethods(cleanerCls, cleanerMethods.data(),
530 cleanerMethods.size())) != ANI_OK) {
531 TAG_LOGE(AAFwkTag::APPKIT, "Class_BindNativeMethods failed status: %{public}d", status);
532 return;
533 }
534 });
535 }
536
CreateEtsApplicationContext(ani_env * aniEnv,const std::shared_ptr<ApplicationContext> & applicationContext)537 ani_object EtsApplicationContextUtils::CreateEtsApplicationContext(ani_env* aniEnv,
538 const std::shared_ptr<ApplicationContext> &applicationContext)
539 {
540 TAG_LOGD(AAFwkTag::APPKIT, "CreateEtsApplicationContext Call");
541 if (applicationContext == nullptr || aniEnv == nullptr) {
542 TAG_LOGE(AAFwkTag::APPKIT, "null applicationContext or aniEnv");
543 return nullptr;
544 }
545 ani_object applicationContextObject = SetApplicationContext(aniEnv, applicationContext);
546 ani_status status = ANI_ERROR;
547 ani_ref applicationContextObjectRef = nullptr;
548 if ((status = aniEnv->GlobalReference_Create(applicationContextObject, &applicationContextObjectRef)) != ANI_OK) {
549 TAG_LOGE(AAFwkTag::APPKIT, "GlobalReference_Create failed status: %{public}d", status);
550 return nullptr;
551 }
552 auto etsReference = std::make_shared<AppExecFwk::ETSNativeReference>();
553 etsReference->aniObj = applicationContextObject;
554 etsReference->aniRef = applicationContextObjectRef;
555 ApplicationContextManager::GetApplicationContextManager().SetEtsGlobalObject(etsReference);
556 BindApplicationContextFunc(aniEnv);
557 ani_class applicationContextClass = nullptr;
558 if ((status = aniEnv->FindClass(ETS_APPLICATION_CONTEXT_CLASS_NAME, &applicationContextClass)) != ANI_OK) {
559 TAG_LOGE(AAFwkTag::APPKIT, "FindClass ApplicationContext failed status: %{public}d", status);
560 return nullptr;
561 }
562 ContextUtil::CreateEtsBaseContext(aniEnv, applicationContextClass, applicationContextObject, applicationContext);
563 ani_ref* contextGlobalRef = new (std::nothrow) ani_ref;
564 if (contextGlobalRef == nullptr) {
565 TAG_LOGE(AAFwkTag::ABILITY, "new ani_ref failed");
566 return nullptr;
567 }
568 if ((status = aniEnv->GlobalReference_Create(applicationContextObject, contextGlobalRef)) != ANI_OK) {
569 TAG_LOGE(AAFwkTag::APPKIT, "GlobalReference_Create failed status: %{public}d", status);
570 delete contextGlobalRef;
571 return nullptr;
572 }
573 applicationContext->Bind(contextGlobalRef);
574 return applicationContextObject;
575 }
576 } // namespace AbilityRuntime
577 } // namespace OHOS