• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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