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.h"
17
18 #include <mutex>
19 #include <sstream>
20 #include "ability_delegator_registry.h"
21 #include "ability_stage_monitor.h"
22 #include "ani_common_want.h"
23 #include "ani_enum_convert.h"
24 #include "ets_ability_monitor.h"
25 #include "ets_context_utils.h"
26 #include "ets_error_utils.h"
27 #include "ets_native_reference.h"
28 #include "hilog_tag_wrapper.h"
29 #include "shell_cmd_result.h"
30
31 namespace OHOS {
32 namespace AbilityDelegatorEts {
33
34 using namespace OHOS::AbilityRuntime;
35
36 std::map<std::weak_ptr<ETSNativeReference>,
37 std::shared_ptr<EtsAbilityMonitor>,
38 std::owner_less<std::weak_ptr<ETSNativeReference>>> g_monitorRecord;
39 std::map<std::weak_ptr<ETSNativeReference>,
40 std::shared_ptr<EtsAbilityStageMonitor>,
41 std::owner_less<std::weak_ptr<ETSNativeReference>>> g_stageMonitorRecord;
42 std::map<std::weak_ptr<ETSNativeReference>, sptr<IRemoteObject>, std::owner_less<>> g_abilityRecord;
43 std::mutex g_mtxMonitorRecord;
44 std::mutex g_mtxStageMonitorRecord;
45 std::mutex g_mutexAbilityRecord;
46
47 namespace {
48 constexpr const char* CONTEXT_CLASS_NAME = "Lapplication/Context/Context;";
49 constexpr const char* SHELL_CMD_RESULT_CLASS_NAME = "Lapplication/shellCmdResult/ShellCmdResultImpl;";
50 constexpr const char* ABILITY_MONITOR_INNER_CLASS_NAME = "Lapplication/AbilityMonitor/AbilityMonitorInner;";
51 constexpr const char* ABILITY_STAGE_MONITOR_INNER_CLASS_NAME =
52 "Lapplication/AbilityStageMonitor/AbilityStageMonitorInner;";
53 constexpr const char* ABILITY_STAGE_CLASS_NAME = "L@ohos/app/ability/AbilityStage/AbilityStage;";
54 constexpr int COMMON_FAILED = 16000100;
55 }
56
EtsAbilityDelegator()57 EtsAbilityDelegator::EtsAbilityDelegator()
58 {
59 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
60 if (delegator) {
61 auto clearFunc = [](const std::shared_ptr<AppExecFwk::BaseDelegatorAbilityProperty> &baseProperty) {
62 auto property = std::static_pointer_cast<AppExecFwk::EtsDelegatorAbilityProperty>(baseProperty);
63 if (!property) {
64 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid property type");
65 return;
66 }
67
68 std::unique_lock<std::mutex> lck(g_mutexAbilityRecord);
69 for (auto it = g_abilityRecord.begin(); it != g_abilityRecord.end();) {
70 if (it->second == property->token_) {
71 it = g_abilityRecord.erase(it);
72 continue;
73 }
74 ++it;
75 }
76 };
77
78 delegator->RegisterClearFunc(clearFunc);
79 }
80 }
81
82 EtsAbilityDelegator::~EtsAbilityDelegator() = default;
83
SetAppContext(ani_env * env,const std::shared_ptr<AbilityRuntime::Context> & context)84 ani_object EtsAbilityDelegator::SetAppContext(ani_env *env, const std::shared_ptr<AbilityRuntime::Context> &context)
85 {
86 if (env == nullptr || context == nullptr) {
87 TAG_LOGE(AAFwkTag::DELEGATOR, "null env or context");
88 return nullptr;
89 }
90 ani_class cls = nullptr;
91 ani_object contextObj = nullptr;
92 ani_method method = nullptr;
93 ani_status status = env->FindClass(CONTEXT_CLASS_NAME, &cls);
94 if (status != ANI_OK) {
95 TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass status: %{public}d", status);
96 return nullptr;
97 }
98 if ((status = env->Class_FindMethod(cls, "<ctor>", ":V", &method)) != ANI_OK) {
99 TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod status: %{public}d", status);
100 return nullptr;
101 }
102 if ((status = env->Object_New(cls, method, &contextObj)) != ANI_OK) {
103 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New status: %{public}d", status);
104 return nullptr;
105 }
106
107 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::Context>(context);
108 if (workContext == nullptr) {
109 TAG_LOGE(AAFwkTag::DELEGATOR, "null workContext");
110 return nullptr;
111 }
112 ani_long nativeContextLong = reinterpret_cast<ani_long>(workContext);
113 if (!ContextUtil::SetNativeContextLong(env, contextObj, nativeContextLong)) {
114 TAG_LOGE(AAFwkTag::DELEGATOR, "SetNativeContextLong failed");
115 delete workContext;
116 workContext = nullptr;
117 return nullptr;
118 }
119 return contextObj;
120 }
WrapShellCmdResult(ani_env * env,std::unique_ptr<AppExecFwk::ShellCmdResult> result)121 ani_object EtsAbilityDelegator::WrapShellCmdResult(ani_env *env, std::unique_ptr<AppExecFwk::ShellCmdResult> result)
122 {
123 TAG_LOGD(AAFwkTag::DELEGATOR, "WrapShellCmdResult called");
124 if (result == nullptr || env == nullptr) {
125 TAG_LOGE(AAFwkTag::DELEGATOR, "result or env is null");
126 return {};
127 }
128 ani_class cls = nullptr;
129 ani_status status = ANI_ERROR;
130 status = env->FindClass(SHELL_CMD_RESULT_CLASS_NAME, &cls);
131 if (status != ANI_OK) {
132 TAG_LOGE(AAFwkTag::DELEGATOR, "find AbilityDelegator failed status: %{public}d", status);
133 return {};
134 }
135 ani_method method = nullptr;
136 status = env->Class_FindMethod(cls, "<ctor>", ":V", &method);
137 if (status != ANI_OK) {
138 TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status);
139 return {};
140 }
141 ani_object object = nullptr;
142 if (env->Object_New(cls, method, &object) != ANI_OK) {
143 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status);
144 return {};
145 }
146 TAG_LOGD(AAFwkTag::DELEGATOR, "Object_New success");
147 ani_field filed = nullptr;
148 status = env->Class_FindField(cls, "stdResult", &filed);
149 if (status != ANI_OK) {
150 TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindField failed status: %{public}d", status);
151 }
152 ani_string aniStringVal = nullptr;
153 std::string strResult = result->GetStdResult();
154 status = env->String_NewUTF8(strResult.c_str(), strResult.size(), &aniStringVal);
155 if (status != ANI_OK) {
156 TAG_LOGE(AAFwkTag::DELEGATOR, "String_NewUTF8 failed status: %{public}d", status);
157 }
158 status = env->Object_SetField_Ref(object, filed, aniStringVal);
159 if (status != ANI_OK) {
160 TAG_LOGE(AAFwkTag::DELEGATOR, "set strResult failed status: %{public}d", status);
161 }
162 int32_t exitCode = result->GetExitCode();
163 status = env->Object_SetPropertyByName_Double(object, "exitCode", exitCode);
164 if (status != ANI_OK) {
165 TAG_LOGE(AAFwkTag::DELEGATOR, "set exitCode failed status: %{public}d", status);
166 }
167 return object;
168 }
169
GetAppContext(ani_env * env,ani_object object,ani_class clss)170 ani_object EtsAbilityDelegator::GetAppContext(ani_env *env, [[maybe_unused]]ani_object object, ani_class clss)
171 {
172 TAG_LOGD(AAFwkTag::DELEGATOR, "GetAppContext call");
173 if (env == nullptr) {
174 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
175 return {};
176 }
177 ani_class cls = nullptr;
178 ani_object nullobj = nullptr;
179 if (ANI_OK != env->FindClass(CONTEXT_CLASS_NAME, &cls)) {
180 TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass Context Failed");
181 return nullobj;
182 }
183 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
184 if (!delegator) {
185 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
186 return nullobj;
187 }
188 std::shared_ptr<AbilityRuntime::Context> context = delegator->GetAppContext();
189 if (!context) {
190 TAG_LOGE(AAFwkTag::DELEGATOR, "null context");
191 return nullobj;
192 }
193 ani_object contextObj = SetAppContext(env, context);
194 if (contextObj == nullptr) {
195 TAG_LOGE(AAFwkTag::DELEGATOR, "null contextObj");
196 return nullobj;
197 }
198 ContextUtil::CreateEtsBaseContext(env, cls, contextObj, context);
199 TAG_LOGD(AAFwkTag::DELEGATOR, "GetAppContext end");
200 return contextObj;
201 }
202
ExecuteShellCommand(ani_env * env,ani_object object,ani_string cmd,ani_double timeoutSecs,ani_object callback)203 void EtsAbilityDelegator::ExecuteShellCommand(ani_env *env, [[maybe_unused]]ani_object object,
204 ani_string cmd, ani_double timeoutSecs, ani_object callback)
205 {
206 TAG_LOGD(AAFwkTag::DELEGATOR, "ExecuteShellCommand called");
207 if (env == nullptr) {
208 TAG_LOGE(AAFwkTag::DELEGATOR, "null env");
209 return;
210 }
211 std::string stdCmd = "";
212 if (!AppExecFwk::GetStdString(env, cmd, stdCmd)) {
213 TAG_LOGE(AAFwkTag::DELEGATOR, "GetStdString Failed");
214 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
215 return;
216 }
217 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
218 if (!delegator) {
219 TAG_LOGE(AAFwkTag::DELEGATOR, "delegator is nullptr");
220 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
221 return;
222 }
223 int resultCode = 0;
224 auto result = delegator->ExecuteShellCommand(stdCmd, static_cast<int64_t>(timeoutSecs));
225 ani_object objValue = WrapShellCmdResult(env, std::move(result));
226 if (objValue == nullptr) {
227 TAG_LOGE(AAFwkTag::DELEGATOR, "null objValue");
228 resultCode = COMMON_FAILED;
229 ani_class cls = nullptr;
230 ani_status status = env->FindClass(SHELL_CMD_RESULT_CLASS_NAME, &cls);
231 if (status != ANI_OK) {
232 TAG_LOGE(AAFwkTag::DELEGATOR, "find AbilityDelegator failed status: %{public}d", status);
233 }
234 ani_method method = nullptr;
235 status = env->Class_FindMethod(cls, "<ctor>", ":V", &method);
236 if (status != ANI_OK) {
237 TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status);
238 }
239 if (env->Object_New(cls, method, &objValue) != ANI_OK) {
240 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status);
241 }
242 }
243 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
244 objValue);
245 return;
246 }
247
FinishTest(ani_env * env,ani_object object,ani_string msg,ani_double code,ani_object callback)248 void EtsAbilityDelegator::FinishTest(ani_env *env, [[maybe_unused]]ani_object object,
249 ani_string msg, ani_double code, ani_object callback)
250 {
251 TAG_LOGD(AAFwkTag::DELEGATOR, "called");
252 if (env == nullptr) {
253 TAG_LOGE(AAFwkTag::DELEGATOR, "null env");
254 return;
255 }
256 std::string stdMsg = "";
257 if (!AppExecFwk::GetStdString(env, msg, stdMsg)) {
258 TAG_LOGE(AAFwkTag::DELEGATOR, "GetStdString Failed");
259 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
260 return;
261 }
262 int resultCode = 0;
263 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
264 if (!delegator) {
265 TAG_LOGE(AAFwkTag::DELEGATOR, "FinishTest delegator is null");
266 resultCode = COMMON_FAILED;
267 } else {
268 delegator->FinishUserTest(stdMsg, static_cast<int64_t>(code));
269 }
270 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
271 nullptr);
272 TAG_LOGD(AAFwkTag::DELEGATOR, "FinishTest END");
273 return;
274 }
275
PrintSync(ani_env * env,ani_class aniClass,ani_string msg)276 void EtsAbilityDelegator::PrintSync(ani_env *env, [[maybe_unused]]ani_class aniClass, ani_string msg)
277 {
278 TAG_LOGD(AAFwkTag::DELEGATOR, "PrintSync");
279 if (env == nullptr) {
280 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
281 return;
282 }
283 std::string msgStr = "";
284 ani_size sz {};
285 env->String_GetUTF8Size(msg, &sz);
286 msgStr.resize(sz + 1);
287 env->String_GetUTF8SubString(msg, 0, sz, msgStr.data(), msgStr.size(), &sz);
288 TAG_LOGD(AAFwkTag::DELEGATOR, "PrintSync %{public}s", msgStr.c_str());
289
290 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
291 if (delegator == nullptr) {
292 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
293 return;
294 }
295
296 delegator->Print(msgStr);
297 return;
298 }
299
RetrieveStringFromAni(ani_env * env,ani_string str,std::string & res)300 void EtsAbilityDelegator::RetrieveStringFromAni(ani_env *env, ani_string str, std::string &res)
301 {
302 if (env == nullptr) {
303 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
304 return;
305 }
306 ani_size sz {};
307 ani_status status = ANI_ERROR;
308 if ((status = env->String_GetUTF8Size(str, &sz)) != ANI_OK) {
309 TAG_LOGE(AAFwkTag::DELEGATOR, "status: %{public}d", status);
310 return;
311 }
312 res.resize(sz + 1);
313 if ((status = env->String_GetUTF8SubString(str, 0, sz, res.data(), res.size(), &sz)) != ANI_OK) {
314 TAG_LOGE(AAFwkTag::DELEGATOR, "status: %{public}d", status);
315 return;
316 }
317 res.resize(sz);
318 }
319
AddAbilityMonitor(ani_env * env,ani_class aniClass,ani_object monitorObj,ani_object callback)320 void EtsAbilityDelegator::AddAbilityMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass,
321 ani_object monitorObj, ani_object callback)
322 {
323 if (env == nullptr) {
324 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
325 return;
326 }
327 std::shared_ptr<EtsAbilityMonitor> monitorImpl = nullptr;
328 if (!ParseMonitorPara(env, monitorObj, monitorImpl)) {
329 TAG_LOGE(AAFwkTag::DELEGATOR, "ParseMonitorPara failed");
330 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
331 return;
332 }
333 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
334 int resultCode = 0;
335 if (delegator == nullptr) {
336 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
337 resultCode = COMMON_FAILED;
338 } else {
339 delegator->AddAbilityMonitor(monitorImpl);
340 }
341 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
342 nullptr);
343 return;
344 }
345
AddAbilityMonitorSync(ani_env * env,ani_class aniClass,ani_object monitorObj)346 void EtsAbilityDelegator::AddAbilityMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
347 ani_object monitorObj)
348 {
349 TAG_LOGD(AAFwkTag::DELEGATOR, "AddAbilityMonitorSync");
350 if (env == nullptr) {
351 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
352 return;
353 }
354 std::shared_ptr<EtsAbilityMonitor> monitorImpl = nullptr;
355 if (!ParseMonitorPara(env, monitorObj, monitorImpl)) {
356 TAG_LOGE(AAFwkTag::DELEGATOR, "ParseMonitorPara failed");
357 AbilityRuntime::EtsErrorUtil::ThrowError(env,
358 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
359 "Parse param monitor failed, monitor must be Monitor.");
360 return;
361 }
362 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
363 if (delegator) {
364 delegator->AddAbilityMonitor(monitorImpl);
365 } else {
366 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
367 AbilityRuntime::EtsErrorUtil::ThrowError(env, COMMON_FAILED, "Calling AddAbilityMonitorSync failed.");
368 }
369 return;
370 }
StartAbility(ani_env * env,ani_object object,ani_object wantObj,ani_object callback)371 void EtsAbilityDelegator::StartAbility(ani_env *env, [[maybe_unused]]ani_object object,
372 ani_object wantObj, ani_object callback)
373 {
374 TAG_LOGD(AAFwkTag::DELEGATOR, "StartAbility");
375 if (env == nullptr) {
376 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
377 return;
378 }
379 AAFwk::Want want;
380 if (!AppExecFwk::UnwrapWant(env, wantObj, want)) {
381 TAG_LOGE(AAFwkTag::DELEGATOR, "UnwrapWant failed");
382 AbilityRuntime::EtsErrorUtil::ThrowError(env,
383 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
384 "Parse want failed, want must be Want.");
385 return;
386 }
387 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
388 if (delegator == nullptr) {
389 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
390 AbilityRuntime::EtsErrorUtil::ThrowError(env, COMMON_FAILED);
391 return;
392 }
393 int resultCode = 0;
394 int result = delegator->StartAbility(want);
395 if (result != ERR_OK) {
396 TAG_LOGE(AAFwkTag::DELEGATOR, "start ability failed: %{public}d", result);
397 resultCode = result;
398 }
399 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
400 nullptr);
401 return;
402 }
403
GetCurrentTopAbility(ani_env * env,ani_class aniClass,ani_object callback)404 ani_ref EtsAbilityDelegator::GetCurrentTopAbility(ani_env* env, [[maybe_unused]]ani_class aniClass,
405 ani_object callback)
406 {
407 TAG_LOGD(AAFwkTag::DELEGATOR, "called");
408 ani_object objValue = nullptr;
409 int32_t resultCode = COMMON_FAILED;
410 std::string resultMsg = "Calling GetCurrentTopAbility failed.";
411 do {
412 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(
413 AbilityRuntime::Runtime::Language::ETS);
414 if (delegator == nullptr) {
415 TAG_LOGE(AAFwkTag::DELEGATOR, "delegator is nullptr");
416 break;
417 }
418 auto property = delegator->GetCurrentTopAbility();
419 auto etsbaseProperty = std::static_pointer_cast<AppExecFwk::EtsDelegatorAbilityProperty>(property);
420 if (etsbaseProperty == nullptr) {
421 TAG_LOGE(AAFwkTag::DELEGATOR, "property is nullptr");
422 break;
423 }
424 auto ability = etsbaseProperty->object_.lock();
425 if (ability == nullptr) {
426 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid property");
427 break;
428 }
429 resultCode = 0;
430 resultMsg = "";
431 std::unique_lock<std::mutex> lck(g_mutexAbilityRecord);
432 g_abilityRecord.emplace(etsbaseProperty->object_, etsbaseProperty->token_);
433 objValue = ability->aniObj;
434 } while (0);
435 ani_ref callbackRef = nullptr;
436 auto status = env->GlobalReference_Create(callback, &callbackRef);
437 if (status != ANI_OK) {
438 TAG_LOGE(AAFwkTag::DELEGATOR, "Create Gloabl ref for delegator failed %{public}d", status);
439 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
440 return objValue;
441 }
442 AppExecFwk::AsyncCallback(env, reinterpret_cast<ani_object>(callbackRef),
443 AbilityRuntime::EtsErrorUtil::CreateError(env, resultCode, resultMsg), objValue);
444 return objValue;
445 }
446
RemoveAbilityMonitor(ani_env * env,ani_class aniClass,ani_object monitorObj,ani_object callback)447 void EtsAbilityDelegator::RemoveAbilityMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass,
448 ani_object monitorObj, ani_object callback)
449 {
450 TAG_LOGD(AAFwkTag::DELEGATOR, "RemoveAbilityMonitor called");
451 if (env == nullptr) {
452 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
453 return;
454 }
455 std::shared_ptr<EtsAbilityMonitor> monitorImpl = nullptr;
456 if (!ParseMonitorPara(env, monitorObj, monitorImpl)) {
457 TAG_LOGE(AAFwkTag::DELEGATOR, "ParseMonitorPara failed");
458 AbilityRuntime::EtsErrorUtil::ThrowError(env,
459 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
460 "Parse monitor failed, removeAbilityMonitor must be Monitor.");
461 return;
462 }
463 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
464 int resultCode = 0;
465 if (delegator == nullptr) {
466 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
467 resultCode = COMMON_FAILED;
468 } else {
469 delegator->RemoveAbilityMonitor(monitorImpl);
470 CleanAndFindMonitorRecord(env, monitorObj);
471 }
472 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
473 nullptr);
474 return;
475 }
476
RemoveAbilityMonitorSync(ani_env * env,ani_class aniClass,ani_object monitorObj)477 void EtsAbilityDelegator::RemoveAbilityMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
478 ani_object monitorObj)
479 {
480 TAG_LOGD(AAFwkTag::DELEGATOR, "RemoveAbilityMonitorSync called");
481 if (env == nullptr) {
482 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
483 return;
484 }
485 std::shared_ptr<EtsAbilityMonitor> monitorImpl = nullptr;
486 if (!ParseMonitorPara(env, monitorObj, monitorImpl)) {
487 TAG_LOGE(AAFwkTag::DELEGATOR, "ParseMonitorPara failed");
488 AbilityRuntime::EtsErrorUtil::ThrowError(env,
489 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
490 "Parse monitor failed, RemoveAbilityMonitorSync must be Monitor.");
491 return;
492 }
493 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
494 if (delegator == nullptr) {
495 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
496 AbilityRuntime::EtsErrorUtil::ThrowError(env, COMMON_FAILED, "Calling RemoveAbilityMonitorSync failed.");
497 return;
498 }
499 delegator->RemoveAbilityMonitor(monitorImpl);
500 CleanAndFindMonitorRecord(env, monitorObj);
501 return;
502 }
503
WaitAbilityMonitor(ani_env * env,ani_class aniClass,ani_object monitorObj,ani_double timeout,ani_object callback)504 void EtsAbilityDelegator::WaitAbilityMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass,
505 ani_object monitorObj, ani_double timeout, ani_object callback)
506 {
507 TAG_LOGD(AAFwkTag::DELEGATOR, "WaitAbilityMonitor called");
508 if (env == nullptr) {
509 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
510 return;
511 }
512 std::shared_ptr<EtsAbilityMonitor> monitorImpl = nullptr;
513 if (!ParseMonitorPara(env, monitorObj, monitorImpl)) {
514 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
515 AbilityRuntime::EtsErrorUtil::ThrowError(env,
516 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
517 "Parse monitor want failed, WaitAbilityMonitor must be Monitor.");
518 return;
519 }
520 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
521 if (delegator == nullptr) {
522 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
523 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
524 return;
525 }
526 std::shared_ptr<BaseDelegatorAbilityProperty> property = (static_cast<int64_t>(timeout) > 0) ?
527 delegator->WaitAbilityMonitor(monitorImpl, static_cast<int64_t>(timeout)) :
528 delegator->WaitAbilityMonitor(monitorImpl);
529 int resultCode = 0;
530 ani_object resultAniOj = nullptr;
531 auto etsbaseProperty = std::static_pointer_cast<AppExecFwk::EtsDelegatorAbilityProperty>(property);
532 if (!etsbaseProperty || etsbaseProperty->object_.expired()) {
533 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid etsbaseProperty");
534 resultCode = COMMON_FAILED;
535 } else {
536 std::unique_lock<std::mutex> lck(g_mutexAbilityRecord);
537 g_abilityRecord.emplace(etsbaseProperty->object_, etsbaseProperty->token_);
538 resultAniOj = etsbaseProperty->object_.lock()->aniObj;
539 }
540 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
541 resultAniOj);
542 return;
543 }
544
AddAbilityStageMonitor(ani_env * env,ani_class aniClass,ani_object stageMonitorObj,ani_object callback)545 void EtsAbilityDelegator::AddAbilityStageMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass,
546 ani_object stageMonitorObj, ani_object callback)
547 {
548 TAG_LOGD(AAFwkTag::DELEGATOR, "AddAbilityStageMonitor called");
549 if (env == nullptr) {
550 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
551 return;
552 }
553 bool isExisted = false;
554 std::shared_ptr<EtsAbilityStageMonitor> stageMonitor = nullptr;
555 if (!ParseStageMonitorPara(env, stageMonitorObj, stageMonitor, isExisted)) {
556 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
557 AbilityRuntime::EtsErrorUtil::ThrowError(env,
558 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
559 "Parse parameters failed, monitor must be Monitor and isExited must be boolean.");
560 return;
561 }
562 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
563 int resultCode = 0;
564 if (delegator == nullptr) {
565 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
566 resultCode = COMMON_FAILED;
567 } else {
568 delegator->AddAbilityStageMonitor(stageMonitor);
569 if (!isExisted) {
570 AddStageMonitorRecord(env, stageMonitorObj, stageMonitor);
571 }
572 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
573 nullptr);
574 }
575 return;
576 }
577
AddAbilityStageMonitorSync(ani_env * env,ani_class aniClass,ani_object stageMonitorObj)578 void EtsAbilityDelegator::AddAbilityStageMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
579 ani_object stageMonitorObj)
580 {
581 TAG_LOGI(AAFwkTag::DELEGATOR, "AddAbilityStageMonitorSync called");
582 if (env == nullptr) {
583 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
584 return;
585 }
586 bool isExisted = false;
587 std::shared_ptr<EtsAbilityStageMonitor> stageMonitor = nullptr;
588 if (!ParseStageMonitorPara(env, stageMonitorObj, stageMonitor, isExisted)) {
589 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
590 AbilityRuntime::EtsErrorUtil::ThrowError(env,
591 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
592 "Parse parameters failed, monitor must be Monitor and isExited must be boolean.");
593 return;
594 }
595 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
596 if (delegator) {
597 delegator->AddAbilityStageMonitor(stageMonitor);
598 if (!isExisted) {
599 AddStageMonitorRecord(env, stageMonitorObj, stageMonitor);
600 }
601 } else {
602 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
603 AbilityRuntime::EtsErrorUtil::ThrowError(env, COMMON_FAILED, "Calling AddAbilityStageMonitorSync failed.");
604 }
605 return;
606 }
607
RemoveAbilityStageMonitor(ani_env * env,ani_class aniClass,ani_object stageMonitorObj,ani_object callback)608 void EtsAbilityDelegator::RemoveAbilityStageMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass,
609 ani_object stageMonitorObj, ani_object callback)
610 {
611 TAG_LOGI(AAFwkTag::DELEGATOR, "RemoveAbilityStageMonitor called");
612 if (env == nullptr) {
613 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
614 return;
615 }
616 bool isExisted = false;
617 std::shared_ptr<EtsAbilityStageMonitor> stageMonitor = nullptr;
618 if (!ParseStageMonitorPara(env, stageMonitorObj, stageMonitor, isExisted)) {
619 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
620 AbilityRuntime::EtsErrorUtil::ThrowError(env,
621 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
622 "Parse monitor failed, removeAbilityMonitor must be Monitor.");
623 return;
624 }
625 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
626 int resultCode = 0;
627 if (delegator == nullptr) {
628 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
629 resultCode = COMMON_FAILED;
630 } else {
631 delegator->RemoveAbilityStageMonitor(stageMonitor);
632 }
633 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
634 nullptr);
635 if (isExisted) {
636 RemoveStageMonitorRecord(env, stageMonitorObj);
637 }
638 return;
639 }
640
RemoveAbilityStageMonitorSync(ani_env * env,ani_class aniClass,ani_object stageMonitorObj)641 void EtsAbilityDelegator::RemoveAbilityStageMonitorSync(ani_env *env, [[maybe_unused]]ani_class aniClass,
642 ani_object stageMonitorObj)
643 {
644 TAG_LOGI(AAFwkTag::DELEGATOR, "RemoveAbilityStageMonitorSync called");
645 if (env == nullptr) {
646 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
647 return;
648 }
649 bool isExisted = false;
650 std::shared_ptr<EtsAbilityStageMonitor> stageMonitor = nullptr;
651 if (!ParseStageMonitorPara(env, stageMonitorObj, stageMonitor, isExisted)) {
652 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
653 AbilityRuntime::EtsErrorUtil::ThrowError(env,
654 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
655 "Parse monitor failed, removeAbilityMonitor must be Monitor.");
656 return;
657 }
658 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
659 if (delegator) {
660 delegator->RemoveAbilityStageMonitor(stageMonitor);
661 } else {
662 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
663 AbilityRuntime::EtsErrorUtil::ThrowError(env, COMMON_FAILED, "Calling RemoveAbilityStageMonitorSync failed.");
664 }
665
666 if (isExisted) {
667 RemoveStageMonitorRecord(env, stageMonitorObj);
668 }
669 return;
670 }
671
WaitAbilityStageMonitor(ani_env * env,ani_class aniClass,ani_object stageMonitorObj,ani_double timeout,ani_object callback)672 void EtsAbilityDelegator::WaitAbilityStageMonitor(ani_env *env, [[maybe_unused]]ani_class aniClass,
673 ani_object stageMonitorObj, ani_double timeout, ani_object callback)
674 {
675 TAG_LOGI(AAFwkTag::DELEGATOR, "WaitAbilityStageMonitor called");
676 if (env == nullptr) {
677 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
678 return;
679 }
680 std::shared_ptr<EtsAbilityStageMonitor> stageMonitor = nullptr;
681 if (!ParseWaitAbilityStageMonitorPara(env, stageMonitorObj, stageMonitor)) {
682 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
683 AbilityRuntime::EtsErrorUtil::ThrowError(env,
684 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
685 "Parse monitor failed, removeAbilityMonitor must be Monitor.");
686 return;
687 }
688 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
689 if (!delegator) {
690 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
691 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
692 return;
693 }
694 std::shared_ptr<BaseDelegatorAbilityStageProperty> result;
695 result = (static_cast<int64_t>(timeout) > 0) ?
696 delegator->WaitAbilityStageMonitor(stageMonitor, static_cast<int64_t>(timeout)) :
697 delegator->WaitAbilityStageMonitor(stageMonitor);
698 int resultCode = 0;
699 ani_object resultAniOj = nullptr;
700 auto etsbaseProperty = std::static_pointer_cast<AppExecFwk::EtsDelegatorAbilityStageProperty>(result);
701 if (CheckPropertyValue(env, resultCode, resultAniOj, etsbaseProperty)) {
702 resultAniOj = etsbaseProperty->object_.lock()->aniObj;
703 }
704 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
705 resultAniOj);
706 return;
707 }
708
DoAbilityForeground(ani_env * env,ani_object object,ani_object abilityObj,ani_object callback)709 void EtsAbilityDelegator::DoAbilityForeground(ani_env *env, [[maybe_unused]]ani_object object,
710 ani_object abilityObj, ani_object callback)
711 {
712 TAG_LOGI(AAFwkTag::DELEGATOR, "DoAbilityForeground called");
713 if (env == nullptr) {
714 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
715 return;
716 }
717 sptr<OHOS::IRemoteObject> remoteObject = nullptr;
718 if (!ParseAbilityCommonPara(env, abilityObj, remoteObject)) {
719 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
720 AbilityRuntime::EtsErrorUtil::ThrowError(env,
721 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
722 "Parse remoteObject failed, remoteObject must be RemoteObject.");
723 return;
724 }
725 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
726 int resultCode = 0;
727 if (!delegator) {
728 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
729 resultCode = COMMON_FAILED;
730 } else {
731 if (!delegator->DoAbilityForeground(remoteObject)) {
732 resultCode = COMMON_FAILED;
733 }
734 }
735 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
736 nullptr);
737 return;
738 }
739
DoAbilityBackground(ani_env * env,ani_object object,ani_object abilityObj,ani_object callback)740 void EtsAbilityDelegator::DoAbilityBackground(ani_env *env, [[maybe_unused]]ani_object object,
741 ani_object abilityObj, ani_object callback)
742 {
743 TAG_LOGI(AAFwkTag::DELEGATOR, "DoAbilityBackground called");
744 if (env == nullptr) {
745 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
746 return;
747 }
748 sptr<OHOS::IRemoteObject> remoteObject = nullptr;
749 if (!ParseAbilityCommonPara(env, abilityObj, remoteObject)) {
750 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
751 AbilityRuntime::EtsErrorUtil::ThrowError(env,
752 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
753 "Parse remoteObject failed, remoteObject must be RemoteObject.");
754 return;
755 }
756 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
757 int resultCode = 0;
758 if (!delegator) {
759 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
760 resultCode = COMMON_FAILED;
761 } else {
762 if (!delegator->DoAbilityBackground(remoteObject)) {
763 resultCode = COMMON_FAILED;
764 }
765 }
766 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
767 nullptr);
768 return;
769 }
770
Print(ani_env * env,ani_object object,ani_string msg,ani_object callback)771 void EtsAbilityDelegator::Print(ani_env *env, [[maybe_unused]]ani_object object,
772 ani_string msg, ani_object callback)
773 {
774 TAG_LOGD(AAFwkTag::DELEGATOR, "Print called");
775 if (env == nullptr) {
776 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
777 return;
778 }
779 std::string strMsg = "";
780 if (!AppExecFwk::GetStdString(env, msg, strMsg)) {
781 TAG_LOGE(AAFwkTag::DELEGATOR, "GetStdString Failed");
782 AbilityRuntime::EtsErrorUtil::ThrowError(env,
783 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
784 "Parse msg failed, msg must be string.");
785 return;
786 }
787 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
788 int resultCode = 0;
789 if (!delegator) {
790 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
791 resultCode = COMMON_FAILED;
792 } else {
793 delegator->Print(strMsg);
794 }
795 AppExecFwk::AsyncCallback(env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
796 nullptr);
797 return;
798 }
799
GetAbilityState(ani_env * env,ani_object object,ani_object abilityObj)800 ani_double EtsAbilityDelegator::GetAbilityState(ani_env *env, [[maybe_unused]]ani_object object, ani_object abilityObj)
801 {
802 TAG_LOGD(AAFwkTag::DELEGATOR, "GetAbilityState called");
803 if (env == nullptr) {
804 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
805 return COMMON_FAILED;
806 }
807 sptr<OHOS::IRemoteObject> remoteObject = nullptr;
808 if (!ParseAbilityCommonPara(env, abilityObj, remoteObject)) {
809 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
810 return COMMON_FAILED;
811 }
812
813 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS);
814 if (!delegator) {
815 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
816 return COMMON_FAILED;
817 }
818 AbilityDelegator::AbilityState lifeState = delegator->GetAbilityState(remoteObject);
819 AbilityLifecycleState abilityLifeState = AbilityLifecycleState::UNINITIALIZED;
820 AbilityLifecycleStateToEts(lifeState, abilityLifeState);
821 return static_cast<ani_double>(abilityLifeState);
822 }
823
AbilityLifecycleStateToEts(const AbilityDelegator::AbilityState & lifeState,AbilityLifecycleState & abilityLifeState)824 void EtsAbilityDelegator::AbilityLifecycleStateToEts(
825 const AbilityDelegator::AbilityState &lifeState, AbilityLifecycleState &abilityLifeState)
826 {
827 TAG_LOGI(AAFwkTag::DELEGATOR, "lifeState: %{public}d", static_cast<int32_t>(lifeState));
828 switch (lifeState) {
829 case AbilityDelegator::AbilityState::STARTED:
830 abilityLifeState = AbilityLifecycleState::CREATE;
831 break;
832 case AbilityDelegator::AbilityState::FOREGROUND:
833 abilityLifeState = AbilityLifecycleState::FOREGROUND;
834 break;
835 case AbilityDelegator::AbilityState::BACKGROUND:
836 abilityLifeState = AbilityLifecycleState::BACKGROUND;
837 break;
838 case AbilityDelegator::AbilityState::STOPPED:
839 abilityLifeState = AbilityLifecycleState::DESTROY;
840 break;
841 default:
842 abilityLifeState = AbilityLifecycleState::UNINITIALIZED;
843 break;
844 }
845 }
846
ParseMonitorPara(ani_env * env,ani_object monitorObj,std::shared_ptr<EtsAbilityMonitor> & monitorImpl)847 bool EtsAbilityDelegator::ParseMonitorPara(ani_env *env, ani_object monitorObj,
848 std::shared_ptr<EtsAbilityMonitor> &monitorImpl)
849 {
850 if (env == nullptr || monitorObj == nullptr) {
851 TAG_LOGE(AAFwkTag::DELEGATOR, "env or monitorObj is nullptr");
852 return false;
853 }
854 {
855 std::unique_lock<std::mutex> lck(g_mtxMonitorRecord);
856 TAG_LOGI(AAFwkTag::DELEGATOR, "monitorRecord size: %{public}zu", g_monitorRecord.size());
857 for (auto iter = g_monitorRecord.begin(); iter != g_monitorRecord.end();) {
858 if (iter->first.expired()) {
859 TAG_LOGE(AAFwkTag::DELEGATOR, "g_monitorRecord expired");
860 iter = g_monitorRecord.erase(iter);
861 continue;
862 }
863 std::shared_ptr<ETSNativeReference> etsMonitor = iter->first.lock();
864 if (etsMonitor == nullptr) {
865 TAG_LOGE(AAFwkTag::DELEGATOR, "etsMonitor is nullptr");
866 iter = g_monitorRecord.erase(iter);
867 continue;
868 }
869 ani_boolean result = false;
870 ani_status status = env->Reference_StrictEquals(reinterpret_cast<ani_ref>(monitorObj),
871 reinterpret_cast<ani_ref>(etsMonitor->aniObj), &result);
872 if (status != ANI_OK) {
873 TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status);
874 }
875 if (result) {
876 monitorImpl = iter->second;
877 return monitorImpl ? true : false;
878 }
879 ++iter;
880 }
881 }
882 if (!ParseMonitorParaInner(env, monitorObj, monitorImpl)) {
883 TAG_LOGE(AAFwkTag::DELEGATOR, "ParseMonitorParaInner failed");
884 return false;
885 }
886 return true;
887 }
888
ParseMonitorParaInner(ani_env * env,ani_object monitorObj,std::shared_ptr<EtsAbilityMonitor> & monitorImpl)889 bool EtsAbilityDelegator::ParseMonitorParaInner(ani_env *env, ani_object monitorObj,
890 std::shared_ptr<EtsAbilityMonitor> &monitorImpl)
891 {
892 if (env == nullptr || monitorObj == nullptr) {
893 TAG_LOGE(AAFwkTag::DELEGATOR, "env or monitorObj is nullptr");
894 return false;
895 }
896 ani_class monitorCls = nullptr;
897 ani_status status = env->FindClass(ABILITY_MONITOR_INNER_CLASS_NAME, &monitorCls);
898 if (status != ANI_OK) {
899 TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass failed status: %{public}d", status);
900 return false;
901 }
902 ani_ref moduleNameRef = nullptr;
903 status = env->Object_GetPropertyByName_Ref(monitorObj, "moduleName", &moduleNameRef);
904 if (ANI_OK != status) {
905 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetField_Ref ");
906 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
907 return false;
908 }
909 std::string strModuleName = "";
910 ani_string aniModuleString = static_cast<ani_string>(moduleNameRef);
911 RetrieveStringFromAni(env, aniModuleString, strModuleName);
912 ani_ref abilityNameRef = nullptr;
913 status = env->Object_GetPropertyByName_Ref(monitorObj, "abilityName", &abilityNameRef);
914 if (ANI_OK != status) {
915 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetField_Ref ");
916 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
917 return false;
918 }
919 std::string strAbilityName = "";
920 ani_string aniAbilityName = static_cast<ani_string>(abilityNameRef);
921 RetrieveStringFromAni(env, aniAbilityName, strAbilityName);
922
923 std::shared_ptr<EtsAbilityMonitor> abilityMonitor = nullptr;
924 if (strModuleName.empty()) {
925 abilityMonitor = std::make_shared<EtsAbilityMonitor>(strAbilityName);
926 abilityMonitor->SetEtsAbilityMonitor(env, monitorObj);
927 } else {
928 abilityMonitor = std::make_shared<EtsAbilityMonitor>(strAbilityName, strModuleName);
929 abilityMonitor->SetEtsAbilityMonitor(env, monitorObj);
930 }
931 monitorImpl = abilityMonitor;
932 std::shared_ptr<ETSNativeReference> reference = std::make_shared<ETSNativeReference>();
933 if (reference != nullptr) {
934 reference->aniObj = monitorObj;
935 }
936 std::unique_lock<std::mutex> lck(g_mtxMonitorRecord);
937 g_monitorRecord.emplace(reference, monitorImpl);
938 return true;
939 }
940
ParseStageMonitorPara(ani_env * env,ani_object stageMonitorObj,std::shared_ptr<EtsAbilityStageMonitor> & stageMonitor,bool & isExisted)941 bool EtsAbilityDelegator::ParseStageMonitorPara(ani_env *env, ani_object stageMonitorObj,
942 std::shared_ptr<EtsAbilityStageMonitor> &stageMonitor, bool &isExisted)
943 {
944 if (env == nullptr || stageMonitorObj == nullptr) {
945 TAG_LOGE(AAFwkTag::DELEGATOR, "env or stageMonitorObj is nullptr");
946 return false;
947 }
948 isExisted = false;
949 {
950 std::unique_lock<std::mutex> lck(g_mtxStageMonitorRecord);
951 TAG_LOGI(AAFwkTag::DELEGATOR, "stageMonitorRecord size: %{public}zu", g_stageMonitorRecord.size());
952 for (auto iter = g_stageMonitorRecord.begin(); iter != g_stageMonitorRecord.end();) {
953 if (iter->first.expired()) {
954 TAG_LOGE(AAFwkTag::DELEGATOR, "g_stageMonitorRecord expired");
955 iter = g_stageMonitorRecord.erase(iter);
956 continue;
957 }
958 std::shared_ptr<ETSNativeReference> etsMonitor = iter->first.lock();
959 if (etsMonitor == nullptr) {
960 TAG_LOGE(AAFwkTag::DELEGATOR, "etsMonitor is nullptr");
961 iter = g_stageMonitorRecord.erase(iter);
962 continue;
963 }
964 ani_boolean result = false;
965 ani_status status = env->Reference_StrictEquals(reinterpret_cast<ani_ref>(stageMonitorObj),
966 reinterpret_cast<ani_ref>(etsMonitor->aniObj), &result);
967 if (status != ANI_OK) {
968 TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status);
969 }
970 if (result) {
971 TAG_LOGW(AAFwkTag::DELEGATOR, "abilityStage monitor exist");
972 isExisted = true;
973 stageMonitor = iter->second;
974 return stageMonitor ? true : false;
975 }
976 ++iter;
977 }
978 }
979 if (!ParseStageMonitorParaInner(env, stageMonitorObj, stageMonitor)) {
980 TAG_LOGE(AAFwkTag::DELEGATOR, "ParseStageMonitorParaInner failed");
981 return false;
982 }
983 return true;
984 }
985
ParseStageMonitorParaInner(ani_env * env,ani_object stageMonitorObj,std::shared_ptr<EtsAbilityStageMonitor> & stageMonitor)986 bool EtsAbilityDelegator::ParseStageMonitorParaInner(ani_env *env, ani_object stageMonitorObj,
987 std::shared_ptr<EtsAbilityStageMonitor> &stageMonitor)
988 {
989 if (env == nullptr || stageMonitorObj == nullptr) {
990 TAG_LOGE(AAFwkTag::DELEGATOR, "env or stageMonitorObj is nullptr");
991 return false;
992 }
993 ani_class monitorCls = nullptr;
994 ani_status status = env->FindClass(ABILITY_STAGE_MONITOR_INNER_CLASS_NAME, &monitorCls);
995 if (status != ANI_OK) {
996 TAG_LOGE(AAFwkTag::DELEGATOR, "FindClass failed status: %{public}d", status);
997 return false;
998 }
999 ani_ref moduleNameRef = nullptr;
1000 status = env->Object_GetPropertyByName_Ref(stageMonitorObj, "moduleName", &moduleNameRef);
1001 if (ANI_OK != status) {
1002 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetField_Ref failed status: %{public}d", status);
1003 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
1004 return false;
1005 }
1006 std::string strModuleName = "";
1007 ani_string aniModuleString = static_cast<ani_string>(moduleNameRef);
1008 RetrieveStringFromAni(env, aniModuleString, strModuleName);
1009 TAG_LOGD(AAFwkTag::DELEGATOR, "strModuleName %{public}s ", strModuleName.c_str());
1010 ani_ref srcEntranceRef = nullptr;
1011 status = env->Object_GetPropertyByName_Ref(stageMonitorObj, "srcEntrance", &srcEntranceRef);
1012 if (ANI_OK != status) {
1013 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_GetField_Ref ");
1014 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
1015 return false;
1016 }
1017 std::string srcEntrance = "";
1018 ani_string aniSrcEntranceRef = static_cast<ani_string>(srcEntranceRef);
1019 RetrieveStringFromAni(env, aniSrcEntranceRef, srcEntrance);
1020 TAG_LOGD(AAFwkTag::DELEGATOR, "srcEntrance %{public}s ", srcEntrance.c_str());
1021 stageMonitor = std::make_shared<EtsAbilityStageMonitor>(strModuleName, srcEntrance);
1022 return true;
1023 }
1024
AddStageMonitorRecord(ani_env * env,ani_object stageMonitorObj,const std::shared_ptr<EtsAbilityStageMonitor> & stageMonitor)1025 void EtsAbilityDelegator::AddStageMonitorRecord(ani_env *env, ani_object stageMonitorObj,
1026 const std::shared_ptr<EtsAbilityStageMonitor> &stageMonitor)
1027 {
1028 TAG_LOGI(AAFwkTag::DELEGATOR, "AddStageMonitorRecord called");
1029 if (env == nullptr || stageMonitor == nullptr) {
1030 TAG_LOGE(AAFwkTag::DELEGATOR, "env or stageMonitor is nullptr");
1031 return;
1032 }
1033 if (!AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS)) {
1034 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
1035 return;
1036 }
1037 std::shared_ptr<ETSNativeReference> reference = std::make_shared<ETSNativeReference>();
1038 reference->aniObj = stageMonitorObj;
1039 {
1040 std::unique_lock<std::mutex> lck(g_mtxStageMonitorRecord);
1041 g_stageMonitorRecord.emplace(reference, stageMonitor);
1042 TAG_LOGI(AAFwkTag::DELEGATOR, "end, size: %{public}zu", g_stageMonitorRecord.size());
1043 }
1044 }
1045
RemoveStageMonitorRecord(ani_env * env,ani_object stageMonitorObj)1046 void EtsAbilityDelegator::RemoveStageMonitorRecord(ani_env *env, ani_object stageMonitorObj)
1047 {
1048 if (env == nullptr) {
1049 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
1050 return;
1051 }
1052 if (!AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator(AbilityRuntime::Runtime::Language::ETS)) {
1053 TAG_LOGE(AAFwkTag::DELEGATOR, "null delegator");
1054 return;
1055 }
1056 std::unique_lock<std::mutex> lck(g_mtxStageMonitorRecord);
1057 for (auto iter = g_stageMonitorRecord.begin(); iter != g_stageMonitorRecord.end();) {
1058 if (iter->first.expired()) {
1059 TAG_LOGE(AAFwkTag::DELEGATOR, "g_stageMonitorRecord expired");
1060 iter = g_stageMonitorRecord.erase(iter);
1061 continue;
1062 }
1063 std::shared_ptr<ETSNativeReference> etsMonitor = iter->first.lock();
1064 if (etsMonitor == nullptr) {
1065 TAG_LOGE(AAFwkTag::DELEGATOR, "etsMonitor is nullptr");
1066 iter = g_stageMonitorRecord.erase(iter);
1067 continue;
1068 }
1069 ani_boolean result = false;
1070 ani_status status = env->Reference_StrictEquals(reinterpret_cast<ani_ref>(stageMonitorObj),
1071 reinterpret_cast<ani_ref>(etsMonitor->aniObj), &result);
1072 if (status != ANI_OK) {
1073 TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status);
1074 }
1075 if (result) {
1076 g_stageMonitorRecord.erase(iter);
1077 TAG_LOGI(AAFwkTag::DELEGATOR, "end, size: %{public}zu", g_stageMonitorRecord.size());
1078 break;
1079 }
1080 ++iter;
1081 }
1082 }
1083
ParseWaitAbilityStageMonitorPara(ani_env * env,ani_object stageMonitorObj,std::shared_ptr<EtsAbilityStageMonitor> & stageMonitor)1084 bool EtsAbilityDelegator::ParseWaitAbilityStageMonitorPara(ani_env *env, ani_object stageMonitorObj,
1085 std::shared_ptr<EtsAbilityStageMonitor> &stageMonitor)
1086 {
1087 TAG_LOGI(AAFwkTag::DELEGATOR, "ParseWaitAbilityStageMonitorPara called");
1088 if (env == nullptr) {
1089 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
1090 return false;
1091 }
1092 bool isExisted = false;
1093 if (!ParseStageMonitorPara(env, stageMonitorObj, stageMonitor, isExisted)) {
1094 TAG_LOGE(AAFwkTag::DELEGATOR, "invalid params");
1095 return false;
1096 }
1097 if (!isExisted) {
1098 AddStageMonitorRecord(env, stageMonitorObj, stageMonitor);
1099 }
1100 return true;
1101 }
1102
ParseAbilityCommonPara(ani_env * env,ani_object abilityObj,sptr<OHOS::IRemoteObject> & remoteObject)1103 bool EtsAbilityDelegator::ParseAbilityCommonPara(ani_env *env, ani_object abilityObj,
1104 sptr<OHOS::IRemoteObject> &remoteObject)
1105 {
1106 TAG_LOGI(AAFwkTag::DELEGATOR, "g_abilityRecord size: %{public}zu", g_abilityRecord.size());
1107 if (env == nullptr) {
1108 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
1109 return false;
1110 }
1111 std::unique_lock<std::mutex> lck(g_mutexAbilityRecord);
1112 for (auto iter = g_abilityRecord.begin(); iter != g_abilityRecord.end();) {
1113 if (iter->first.expired()) {
1114 TAG_LOGE(AAFwkTag::DELEGATOR, "g_abilityRecord expired");
1115 iter = g_abilityRecord.erase(iter);
1116 continue;
1117 }
1118 std::shared_ptr<ETSNativeReference> etsMonitor = iter->first.lock();
1119 if (etsMonitor == nullptr) {
1120 TAG_LOGE(AAFwkTag::DELEGATOR, "etsMonitor is null");
1121 iter = g_abilityRecord.erase(iter);
1122 continue;
1123 }
1124 ani_boolean result = false;
1125 ani_status status = env->Reference_StrictEquals(reinterpret_cast<ani_ref>(etsMonitor->aniObj),
1126 reinterpret_cast<ani_ref>(abilityObj), &result);
1127 if (status != ANI_OK) {
1128 TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status);
1129 }
1130 if (result) {
1131 remoteObject = iter->second;
1132 TAG_LOGI(AAFwkTag::DELEGATOR, "ability exist");
1133 return remoteObject ? true : false;
1134 }
1135 ++iter;
1136 }
1137 TAG_LOGE(AAFwkTag::DELEGATOR, "ability not exist");
1138 remoteObject = nullptr;
1139 return false;
1140 }
1141
CheckPropertyValue(ani_env * env,int & resultCode,ani_object & resultAniOj,std::shared_ptr<AppExecFwk::EtsDelegatorAbilityStageProperty> etsProperty)1142 bool EtsAbilityDelegator::CheckPropertyValue(ani_env *env, int &resultCode, ani_object &resultAniOj,
1143 std::shared_ptr<AppExecFwk::EtsDelegatorAbilityStageProperty> etsProperty)
1144 {
1145 if (env == nullptr) {
1146 TAG_LOGE(AAFwkTag::DELEGATOR, "env is nullptr");
1147 return false;
1148 }
1149 if (!etsProperty || etsProperty->object_.expired()) {
1150 TAG_LOGE(AAFwkTag::DELEGATOR, "waitAbilityStageMonitor failed");
1151 resultCode = COMMON_FAILED;
1152 ani_class cls = nullptr;
1153 ani_status status = env->FindClass(ABILITY_STAGE_CLASS_NAME, &cls);
1154 if (status != ANI_OK) {
1155 TAG_LOGE(AAFwkTag::DELEGATOR, "find AbilityDelegator failed status: %{public}d", status);
1156 }
1157 ani_method method = nullptr;
1158 status = env->Class_FindMethod(cls, "<ctor>", ":V", &method);
1159 if (status != ANI_OK) {
1160 TAG_LOGE(AAFwkTag::DELEGATOR, "Class_FindMethod ctor failed status: %{public}d", status);
1161 }
1162 if (env->Object_New(cls, method, &resultAniOj) != ANI_OK) {
1163 TAG_LOGE(AAFwkTag::DELEGATOR, "Object_New failed status: %{public}d", status);
1164 }
1165 return false;
1166 }
1167 return true;
1168 }
1169
CleanAndFindMonitorRecord(ani_env * env,ani_object monitorObj)1170 void EtsAbilityDelegator::CleanAndFindMonitorRecord(ani_env *env, ani_object monitorObj)
1171 {
1172 if (env == nullptr || monitorObj == nullptr) {
1173 TAG_LOGE(AAFwkTag::DELEGATOR, "env or monitorObj is nullptr");
1174 return;
1175 }
1176 std::unique_lock<std::mutex> lck(g_mtxMonitorRecord);
1177 for (auto iter = g_monitorRecord.begin(); iter != g_monitorRecord.end();) {
1178 if (iter->first.expired()) {
1179 TAG_LOGE(AAFwkTag::DELEGATOR, "g_monitorRecord expired");
1180 iter = g_monitorRecord.erase(iter);
1181 continue;
1182 }
1183 std::shared_ptr<ETSNativeReference> etsMonitor = iter->first.lock();
1184 if (etsMonitor == nullptr) {
1185 TAG_LOGE(AAFwkTag::DELEGATOR, "etsMonitor is null");
1186 iter = g_monitorRecord.erase(iter);
1187 continue;
1188 }
1189 ani_boolean result = false;
1190 ani_status status = env->Reference_StrictEquals(reinterpret_cast<ani_ref>(monitorObj),
1191 reinterpret_cast<ani_ref>(etsMonitor->aniObj), &result);
1192 if (status != ANI_OK) {
1193 TAG_LOGE(AAFwkTag::DELEGATOR, "Reference_StrictEquals failed status: %{public}d", status);
1194 }
1195 if (result) {
1196 g_monitorRecord.erase(iter);
1197 break;
1198 }
1199 ++iter;
1200 }
1201 }
1202 } // namespace AbilityDelegatorEts
1203 } // namespace OHOS
1204