• 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 
16 #include "ets_ability_delegator_utils.h"
17 
18 #include <map>
19 #include "ets_ability_delegator.h"
20 #include "hilog_tag_wrapper.h"
21 
22 namespace OHOS {
23 namespace AbilityDelegatorEts {
24 namespace {
25 constexpr const char* ABILITY_DELEGATOR_CLASS_NAME = "Lapplication/AbilityDelegator/AbilityDelegatorInner;";
26 constexpr const char* RECORD_CLASS_NAME = "Lescompat/Record;";
27 constexpr const char* VOID_CONTEXT = ":Lapplication/Context/Context;";
28 constexpr const char* STRING_NUMBER_ASYNCCALLBACK = "Lstd/core/String;DLutils/AbilityUtils/AsyncCallbackWrapper;:V";
29 constexpr const char* STRING_VOID = "Lstd/core/String;:V";
30 constexpr const char* MONITOR_ASYNCCALLBACK_VOID =
31     "Lapplication/AbilityMonitor/AbilityMonitor;Lutils/AbilityUtils/AsyncCallbackWrapper;:V";
32 constexpr const char* WANT_ASYNCCALLBACK = "L@ohos/app/ability/Want/Want;Lutils/AbilityUtils/AsyncCallbackWrapper;:V";
33 constexpr const char* ARGS_ABILITY_DELEGATOR_CLASS_NAME =
34     "Lapplication/abilityDelegatorArgs/AbilityDelegatorArgsInner;";
35 constexpr const char* SIGNATURE_MONITOR_VOID = "Lapplication/AbilityMonitor/AbilityMonitor;:V";
36 constexpr const char* SIGNATURE_MONITOR_NUMBER_ASYNCCALLBACK =
37     "Lapplication/AbilityMonitor/AbilityMonitor;DLutils/AbilityUtils/AsyncCallbackWrapper;:V";
38 constexpr const char* STAGEMONITOR_ASYNCCALLBACK_VOID =
39     "Lapplication/AbilityStageMonitor/AbilityStageMonitor;Lutils/AbilityUtils/AsyncCallbackWrapper;:V";
40 constexpr const char* STAGEMONITOR_VOID =
41     "Lapplication/AbilityStageMonitor/AbilityStageMonitor;:V";
42 constexpr const char* SIGNATURE_STAGEMONITOR_NUMBER_ASYNCCALLBACK =
43     "Lapplication/AbilityStageMonitor/AbilityStageMonitor;DLutils/AbilityUtils/AsyncCallbackWrapper;:V";
44 constexpr const char* STAGEMONITOR_UIABILITY_ASYNCCALLBACK =
45     "L@ohos/app/ability/UIAbility/UIAbility;Lutils/AbilityUtils/AsyncCallbackWrapper;:V";
46 constexpr const char* STRING_ASYNCCALLBACK_VOID = "Lstd/core/String;Lutils/AbilityUtils/AsyncCallbackWrapper;:V";
47 constexpr const char* STRING_UIABILITY_NUMBER = "L@ohos/app/ability/UIAbility/UIAbility;:D";
48 constexpr const char* STRING_CALLBACK_UIABILITY =
49     "Lutils/AbilityUtils/AsyncCallbackWrapper;:L@ohos/app/ability/UIAbility/UIAbility;";
50 }
51 
BindFunctions(ani_env * aniEnv,ani_class abilityDelegator)52 bool BindFunctions(ani_env *aniEnv, ani_class abilityDelegator)
53 {
54     if (aniEnv == nullptr) {
55         return false;
56     }
57     std::array functions = {
58         ani_native_function {"getAppContext", VOID_CONTEXT,
59             reinterpret_cast<void *>(EtsAbilityDelegator::GetAppContext)},
60         ani_native_function {"nativeExecuteShellCommand", STRING_NUMBER_ASYNCCALLBACK,
61             reinterpret_cast<void *>(EtsAbilityDelegator::ExecuteShellCommand)},
62         ani_native_function {"nativeFinishTest", STRING_NUMBER_ASYNCCALLBACK,
63             reinterpret_cast<void *>(EtsAbilityDelegator::FinishTest)},
64         ani_native_function {"printSync", STRING_VOID, reinterpret_cast<void *>(EtsAbilityDelegator::PrintSync)},
65         ani_native_function {"nativeAddAbilityMonitor", MONITOR_ASYNCCALLBACK_VOID,
66             reinterpret_cast<void *>(EtsAbilityDelegator::AddAbilityMonitor)},
67         ani_native_function {"nativeStartAbility", WANT_ASYNCCALLBACK,
68             reinterpret_cast<void *>(EtsAbilityDelegator::StartAbility)},
69         ani_native_function {"addAbilityMonitorSync", SIGNATURE_MONITOR_VOID,
70             reinterpret_cast<void *>(EtsAbilityDelegator::AddAbilityMonitorSync)},
71         ani_native_function {"removeAbilityMonitorAsync", MONITOR_ASYNCCALLBACK_VOID,
72             reinterpret_cast<void *>(EtsAbilityDelegator::RemoveAbilityMonitor)},
73         ani_native_function {"removeAbilityMonitorSync", SIGNATURE_MONITOR_VOID,
74             reinterpret_cast<void *>(EtsAbilityDelegator::RemoveAbilityMonitorSync)},
75         ani_native_function {"waitAbilityMonitorAsync", SIGNATURE_MONITOR_NUMBER_ASYNCCALLBACK,
76             reinterpret_cast<void *>(EtsAbilityDelegator::WaitAbilityMonitor)},
77         ani_native_function {"addAbilityStageMonitorAsync", STAGEMONITOR_ASYNCCALLBACK_VOID,
78             reinterpret_cast<void *>(EtsAbilityDelegator::AddAbilityStageMonitor)},
79         ani_native_function {"addAbilityStageMonitorSync", STAGEMONITOR_VOID,
80             reinterpret_cast<void *>(EtsAbilityDelegator::AddAbilityStageMonitorSync)},
81         ani_native_function {"removeAbilityStageMonitorAsync", STAGEMONITOR_ASYNCCALLBACK_VOID,
82             reinterpret_cast<void *>(EtsAbilityDelegator::RemoveAbilityStageMonitor)},
83         ani_native_function {"removeAbilityStageMonitorSync", STAGEMONITOR_VOID,
84             reinterpret_cast<void *>(EtsAbilityDelegator::RemoveAbilityStageMonitorSync)},
85         ani_native_function {"waitAbilityStageMonitorAsync", SIGNATURE_STAGEMONITOR_NUMBER_ASYNCCALLBACK,
86             reinterpret_cast<void *>(EtsAbilityDelegator::WaitAbilityStageMonitor)},
87         ani_native_function {"doAbilityForegroundAsync", STAGEMONITOR_UIABILITY_ASYNCCALLBACK,
88             reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityForeground)},
89         ani_native_function {"doAbilityBackgroundAsync", STAGEMONITOR_UIABILITY_ASYNCCALLBACK,
90             reinterpret_cast<void *>(EtsAbilityDelegator::DoAbilityBackground)},
91         ani_native_function {"printAsync", STRING_ASYNCCALLBACK_VOID,
92             reinterpret_cast<void *>(EtsAbilityDelegator::Print)},
93         ani_native_function {"getAbilityState", STRING_UIABILITY_NUMBER,
94             reinterpret_cast<void *>(EtsAbilityDelegator::GetAbilityState)},
95         ani_native_function {"nativeGetCurrentTopAbility", STRING_CALLBACK_UIABILITY,
96             reinterpret_cast<void *>(EtsAbilityDelegator::GetCurrentTopAbility)}
97     };
98     ani_status status = aniEnv->Class_BindNativeMethods(abilityDelegator, functions.data(), functions.size());
99     if (status != ANI_OK) {
100         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_BindNativeMethods failed status: %{public}d", status);
101         return false;
102     }
103     return true;
104 }
105 
CreateEtsAbilityDelegator(ani_env * aniEnv)106 ani_object CreateEtsAbilityDelegator(ani_env *aniEnv)
107 {
108     TAG_LOGD(AAFwkTag::DELEGATOR, "CreateEtsAbilityDelegator");
109     if (aniEnv == nullptr) {
110         TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv");
111         return {};
112     }
113     ani_class abilityDelegator = nullptr;
114     ani_status status = ANI_ERROR;
115     status = aniEnv->FindClass(ABILITY_DELEGATOR_CLASS_NAME, &abilityDelegator);
116     if (status != ANI_OK) {
117         TAG_LOGE(AAFwkTag::DELEGATOR, "find AbilityDelegatorInner failed status: %{public}d", status);
118         return {};
119     }
120     TAG_LOGD(AAFwkTag::DELEGATOR, "find AbilityDelegator success");
121 
122     if (!BindFunctions(aniEnv, abilityDelegator)) {
123         TAG_LOGE(AAFwkTag::DELEGATOR, "BindFunctions failed");
124         return {};
125     }
126 
127     ani_method method = nullptr;
128     status = aniEnv->Class_FindMethod(abilityDelegator, "<ctor>", ":V", &method);
129     if (status != ANI_OK) {
130         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status);
131         return {};
132     }
133     TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod ctor success");
134 
135     ani_object object = nullptr;
136     if (aniEnv->Object_New(abilityDelegator, method, &object) != ANI_OK) {
137         TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status);
138         return {};
139     }
140 
141     TAG_LOGD(AAFwkTag::DELEGATOR, "CreateEtsAbilityDelegator success");
142     return object;
143 }
144 
SetBundleName(ani_env * aniEnv,ani_class arguments,ani_object argumentObject,const std::string & bundleName)145 void SetBundleName(ani_env *aniEnv, ani_class arguments, ani_object argumentObject, const std::string &bundleName)
146 {
147     if (aniEnv == nullptr) {
148         TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv");
149         return;
150     }
151     ani_status status = ANI_ERROR;
152     ani_string aniStr = nullptr;
153     // Get a ani_string from std::string
154     status = aniEnv->String_NewUTF8(bundleName.c_str(), bundleName.length(), &aniStr);
155     if (status != ANI_OK) {
156         TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status);
157         return;
158     }
159     TAG_LOGD(AAFwkTag::DELEGATOR, "String_NewUTF8 success");
160 
161     // find the setter method
162     ani_method nameSetter = nullptr;
163     status = aniEnv->Class_FindMethod(arguments, "<set>bundleName", nullptr, &nameSetter);
164     if (status != ANI_OK) {
165         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status);
166         return;
167     }
168     TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod success");
169 
170     // call set bundleName(n:string)
171     status = aniEnv->Object_CallMethod_Void(argumentObject, nameSetter, aniStr);
172     if (status != ANI_OK) {
173         TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status);
174         return;
175     }
176     TAG_LOGD(AAFwkTag::DELEGATOR, "Object_CallMethod_Void success");
177 }
178 
SetParameters(ani_env * aniEnv,ani_class arguments,ani_object argumentObject,const std::map<std::string,std::string> & paras)179 void SetParameters(ani_env *aniEnv, ani_class arguments, ani_object argumentObject,
180     const std::map<std::string, std::string> &paras)
181 {
182     TAG_LOGD(AAFwkTag::DELEGATOR, "SetParameters begin");
183     if (aniEnv == nullptr) {
184         TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv");
185         return;
186     }
187     ani_status status = ANI_ERROR;
188     ani_class recordCls = nullptr;
189     status = aniEnv->FindClass(RECORD_CLASS_NAME, &recordCls);
190     if (status != ANI_OK) {
191         TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass failed status: %{public}d", status);
192         return;
193     }
194     ani_method recordGetMethod = nullptr;
195     status = aniEnv->Class_FindMethod(recordCls, "$_get", "Lstd/core/Object;:Lstd/core/Object;", &recordGetMethod);
196     if (status != ANI_OK) {
197         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status);
198         return;
199     }
200     ani_method recordSetMethod = nullptr;
201     status = aniEnv->Class_FindMethod(recordCls, "$_set", "Lstd/core/Object;Lstd/core/Object;:V", &recordSetMethod);
202     if (status != ANI_OK) {
203         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status);
204         return;
205     }
206     ani_ref parameterRef = nullptr;
207     status = aniEnv->Object_CallMethodByName_Ref(argumentObject, "<get>parameters", ":Lescompat/Record;",
208         &parameterRef);
209     if (status != ANI_OK) {
210         TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethodByName_Ref failed status: %{public}d", status);
211         return;
212     }
213     ani_object parameterObject = static_cast<ani_object>(parameterRef);
214     for (auto iter = paras.begin(); iter != paras.end(); ++iter) {
215         std::string key = iter->first;
216         std::string value = iter->second;
217         ani_string ani_key = nullptr;
218         ani_string ani_value = nullptr;
219         status = aniEnv->String_NewUTF8(key.c_str(), key.length(), &ani_key);
220         if (status != ANI_OK) {
221             TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 key failed status: %{public}d", status);
222             return;
223         }
224         status = aniEnv->String_NewUTF8(value.c_str(), value.length(), &ani_value);
225         if (status != ANI_OK) {
226             TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 value failed status: %{public}d", status);
227             return;
228         }
229         status = aniEnv->Object_CallMethod_Void(parameterObject, recordSetMethod, ani_key, ani_value);
230         if (status != ANI_OK) {
231             TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status);
232             return;
233         }
234     }
235     TAG_LOGD(AAFwkTag::DELEGATOR, "SetParameters end");
236 }
237 
SetTestCaseNames(ani_env * aniEnv,ani_class arguments,ani_object argumentObject,const std::string & testcaseNames)238 void SetTestCaseNames(ani_env *aniEnv, ani_class arguments, ani_object argumentObject, const std::string &testcaseNames)
239 {
240     if (aniEnv == nullptr) {
241         TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv");
242         return;
243     }
244     ani_status status = ANI_ERROR;
245     ani_string aniStr = nullptr;
246     status = aniEnv->String_NewUTF8(testcaseNames.c_str(), testcaseNames.length(), &aniStr);
247     if (status != ANI_OK) {
248         TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status);
249         return;
250     }
251     TAG_LOGD(AAFwkTag::DELEGATOR, "String_NewUTF8 success");
252 
253     // find the setter method
254     ani_method nameSetter = nullptr;
255     status = aniEnv->Class_FindMethod(arguments, "<set>testCaseNames", nullptr, &nameSetter);
256     if (status != ANI_OK) {
257         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status);
258         return;
259     }
260     TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod success");
261 
262     // call set testcaseNames(n:string)
263     status = aniEnv->Object_CallMethod_Void(argumentObject, nameSetter, aniStr);
264     if (status != ANI_OK) {
265         TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status);
266         return;
267     }
268     TAG_LOGD(AAFwkTag::DELEGATOR, "Object_CallMethod_Void success");
269 }
270 
SetTestRunnerClassName(ani_env * aniEnv,ani_class arguments,ani_object argumentObject,const std::string & className)271 void SetTestRunnerClassName(ani_env *aniEnv, ani_class arguments, ani_object argumentObject,
272     const std::string &className)
273 {
274     if (aniEnv == nullptr) {
275         TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv");
276         return;
277     }
278     ani_status status = ANI_ERROR;
279     ani_string aniStr = nullptr;
280     status = aniEnv->String_NewUTF8(className.c_str(), className.length(), &aniStr);
281     if (status != ANI_OK) {
282         TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status);
283         return;
284     }
285     TAG_LOGD(AAFwkTag::DELEGATOR, "String_NewUTF8 success");
286 
287     // find the setter method
288     ani_method nameSetter = nullptr;
289     status = aniEnv->Class_FindMethod(arguments, "<set>testRunnerClassName", nullptr, &nameSetter);
290     if (status != ANI_OK) {
291         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod failed status: %{public}d", status);
292         return;
293     }
294     TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod success");
295 
296     // call set testRunnerClassName(n:string)
297     status = aniEnv->Object_CallMethod_Void(argumentObject, nameSetter, aniStr);
298     if (status != ANI_OK) {
299         TAG_LOGE(AAFwkTag::DELEGATOR, "Object_CallMethod_Void failed status: %{public}d", status);
300         return;
301     }
302     TAG_LOGD(AAFwkTag::DELEGATOR, "Object_CallMethod_Void success");
303 }
304 
CreateEtsAbilityDelegatorArguments(ani_env * aniEnv,const std::shared_ptr<AppExecFwk::AbilityDelegatorArgs> abilityDelegatorArgs)305 ani_object CreateEtsAbilityDelegatorArguments(
306     ani_env *aniEnv, const std::shared_ptr<AppExecFwk::AbilityDelegatorArgs> abilityDelegatorArgs)
307 {
308     TAG_LOGD(AAFwkTag::DELEGATOR, "CreateJsAbilityDelegatorArguments");
309     if (aniEnv == nullptr || abilityDelegatorArgs == nullptr) {
310         TAG_LOGE(AAFwkTag::DELEGATOR, "null aniEnv or abilityDelegatorArgs");
311         return {};
312     }
313     ani_class arguments = nullptr;
314     ani_status status = ANI_ERROR;
315     status = aniEnv->FindClass(ARGS_ABILITY_DELEGATOR_CLASS_NAME, &arguments);
316     if (status != ANI_OK) {
317         TAG_LOGE(AAFwkTag::DELEGATOR, "find abilityDelegatorArgs failed status: %{public}d", status);
318         return {};
319     }
320     TAG_LOGD(AAFwkTag::DELEGATOR, "find AbilityDelegatorArgs success");
321 
322     ani_method method = nullptr;
323     status = aniEnv->Class_FindMethod(arguments, "<ctor>", ":V", &method);
324     if (status != ANI_OK) {
325         TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status);
326         return {};
327     }
328     TAG_LOGD(AAFwkTag::DELEGATOR, "Class_FindMethod ctor success");
329 
330     ani_object argumentObject = nullptr;
331     status = aniEnv->Object_New(arguments, method, &argumentObject);
332     if (status != ANI_OK) {
333         TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status);
334         return {};
335     }
336     TAG_LOGD(AAFwkTag::DELEGATOR, "Object_New success");
337 
338     std::string bundleName = abilityDelegatorArgs->GetTestBundleName();
339     SetBundleName(aniEnv, arguments, argumentObject, bundleName);
340 
341     std::string testcaseName = abilityDelegatorArgs->GetTestCaseName();
342     SetTestCaseNames(aniEnv, arguments, argumentObject, testcaseName);
343 
344     std::string className = abilityDelegatorArgs->GetTestRunnerClassName();
345     SetTestRunnerClassName(aniEnv, arguments, argumentObject, className);
346 
347     auto parameters = abilityDelegatorArgs->GetTestParam();
348     SetParameters(aniEnv, arguments, argumentObject, parameters);
349 
350     return argumentObject;
351 }
352 } // namespace AbilityDelegatorEts
353 } // namespace OHOS
354