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_manager.h"
17
18 #include "ability_business_error.h"
19 #include "ability_manager_client.h"
20 #include "ability_manager_errors.h"
21 #include "ability_manager_interface.h"
22 #include "ani_common_ability_state_data.h"
23 #include "ani_common_want.h"
24 #include "ets_error_utils.h"
25 #include "hilog_tag_wrapper.h"
26 #include "if_system_ability_manager.h"
27 #include "ipc_skeleton.h"
28 #include "iservice_registry.h"
29 #include "system_ability_definition.h"
30 #include "tokenid_kit.h"
31
32 namespace OHOS {
33 namespace AbilityRuntime {
34 namespace {
35 constexpr const char* ETS_ABILITY_MANAGER_NAMESPACE = "L@ohos/app/ability/abilityManager/abilityManager;";
36 constexpr const char* ETS_ABILITY_MANAGER_SIGNATURE_ARRAY = ":Lescompat/Array;";
37 constexpr const char* ETS_ABILITY_MANAGER_SIGNATURE_CALLBACK = "Lutils/AbilityUtils/AsyncCallbackWrapper;:V";
38 constexpr int32_t ERR_FAILURE = -1;
39 }
40
GetAbilityManagerInstance()41 sptr<AppExecFwk::IAbilityManager> GetAbilityManagerInstance()
42 {
43 sptr<ISystemAbilityManager> systemAbilityManager =
44 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
45 sptr<IRemoteObject> abilityManagerObj =
46 systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
47 return iface_cast<AppExecFwk::IAbilityManager>(abilityManagerObj);
48 }
GetForegroundUIAbilities(ani_env * env)49 static ani_object GetForegroundUIAbilities(ani_env *env)
50 {
51 TAG_LOGD(AAFwkTag::ABILITYMGR, "call GetForegroundUIAbilities");
52
53 if (env == nullptr) {
54 TAG_LOGE(AAFwkTag::ABILITYMGR, "null env");
55 return nullptr;
56 }
57
58 sptr<AppExecFwk::IAbilityManager> abilityManager = GetAbilityManagerInstance();
59 if (abilityManager == nullptr) {
60 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityManager is null");
61 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
62 return nullptr;
63 }
64 std::vector<AppExecFwk::AbilityStateData> list;
65 int32_t ret = abilityManager->GetForegroundUIAbilities(list);
66 if (ret != ERR_OK) {
67 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed: ret=%{public}d", ret);
68 AbilityRuntime::AbilityErrorCode code = AbilityRuntime::GetJsErrorCodeByNativeError(ret);
69 AbilityRuntime::EtsErrorUtil::ThrowError(env, code);
70 return nullptr;
71 }
72 TAG_LOGD(AAFwkTag::ABILITYMGR, "GetForegroundUIAbilities succeeds, list.size=%{public}zu", list.size());
73 ani_object aniArray = AppExecFwk::CreateAniAbilityStateDataArray(env, list);
74 if (aniArray == nullptr) {
75 TAG_LOGE(AAFwkTag::ABILITYMGR, "null aniArray");
76 AbilityRuntime::EtsErrorUtil::ThrowError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
77 return nullptr;
78 }
79 return aniArray;
80 }
81
GetTopAbility(ani_env * env,ani_object callback)82 static void GetTopAbility(ani_env *env, ani_object callback)
83 {
84 TAG_LOGD(AAFwkTag::ABILITYMGR, "call GetTopAbility");
85 if (env == nullptr) {
86 TAG_LOGE(AAFwkTag::ABILITYMGR, "null env");
87 return;
88 }
89 auto selfToken = IPCSkeleton::GetSelfTokenID();
90 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
91 TAG_LOGE(AAFwkTag::ABILITYMGR, "not system app");
92 AppExecFwk::AsyncCallback(env, callback,
93 EtsErrorUtil::CreateError(env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_NOT_SYSTEM_APP), nullptr);
94 return;
95 }
96 AppExecFwk::ElementName elementName = AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility();
97 int resultCode = 0;
98 ani_object elementNameobj = AppExecFwk::WrapElementName(env, elementName);
99 if (elementNameobj == nullptr) {
100 TAG_LOGE(AAFwkTag::ABILITYMGR, "null elementNameobj");
101 resultCode = ERR_FAILURE;
102 }
103 AppExecFwk::AsyncCallback(env, callback, EtsErrorUtil::CreateErrorByNativeErr(env, resultCode),
104 elementNameobj);
105 return;
106 }
107
EtsAbilityManagerRegistryInit(ani_env * env)108 void EtsAbilityManagerRegistryInit(ani_env *env)
109 {
110 TAG_LOGD(AAFwkTag::ABILITYMGR, "call EtsAbilityManagerRegistryInit");
111 if (env == nullptr) {
112 TAG_LOGE(AAFwkTag::ABILITYMGR, "null env");
113 return;
114 }
115 ani_status status = ANI_ERROR;
116 if (env->ResetError() != ANI_OK) {
117 TAG_LOGE(AAFwkTag::ABILITYMGR, "ResetError failed");
118 }
119 ani_namespace ns = nullptr;
120 status = env->FindNamespace(ETS_ABILITY_MANAGER_NAMESPACE, &ns);
121 if (status != ANI_OK) {
122 TAG_LOGE(AAFwkTag::ABILITYMGR, "FindNamespace abilityManager failed status : %{public}d", status);
123 return;
124 }
125 std::array methods = {
126 ani_native_function {
127 "nativeGetForegroundUIAbilities", ETS_ABILITY_MANAGER_SIGNATURE_ARRAY,
128 reinterpret_cast<void *>(GetForegroundUIAbilities)
129 },
130 ani_native_function {"nativeGetTopAbility", ETS_ABILITY_MANAGER_SIGNATURE_CALLBACK,
131 reinterpret_cast<void *>(GetTopAbility)},
132 };
133 status = env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size());
134 if (status != ANI_OK) {
135 TAG_LOGE(AAFwkTag::ABILITYMGR, "Namespace_BindNativeFunctions failed status : %{public}d", status);
136 }
137 if (env->ResetError() != ANI_OK) {
138 TAG_LOGE(AAFwkTag::ABILITYMGR, "ResetError failed");
139 }
140 }
141
142 extern "C" {
ANI_Constructor(ani_vm * vm,uint32_t * result)143 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
144 {
145 TAG_LOGD(AAFwkTag::ABILITYMGR, "in AbilityManagerEts.ANI_Constructor");
146 if (vm == nullptr || result == nullptr) {
147 TAG_LOGE(AAFwkTag::ABILITYMGR, "null vm or result");
148 return ANI_INVALID_ARGS;
149 }
150
151 ani_env *env = nullptr;
152 ani_status status = ANI_ERROR;
153 status = vm->GetEnv(ANI_VERSION_1, &env);
154 if (status != ANI_OK) {
155 TAG_LOGE(AAFwkTag::ABILITYMGR, "GetEnv failed, status=%{public}d", status);
156 return ANI_NOT_FOUND;
157 }
158 EtsAbilityManagerRegistryInit(env);
159 *result = ANI_VERSION_1;
160 TAG_LOGD(AAFwkTag::ABILITYMGR, "AbilityManagerEts.ANI_Constructor finished");
161 return ANI_OK;
162 }
163 }
164 } // namespace AbilityManagerEts
165 } // namespace OHOS