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_app_manager.h"
17
18 #include "ability_manager_client.h"
19 #include "ability_manager_interface.h"
20 #include "ani_common_util.h"
21 #include "ani_enum_convert.h"
22 #include "app_mgr_constants.h"
23 #include "app_mgr_interface.h"
24 #include "ets_app_manager_utils.h"
25 #include "ets_error_utils.h"
26 #include "hilog_tag_wrapper.h"
27 #include "if_system_ability_manager.h"
28 #include "ipc_skeleton.h"
29 #include "iservice_registry.h"
30 #include "system_ability_definition.h"
31 #ifdef SUPPORT_GRAPHICS
32 #ifdef SUPPORT_SCREEN
33 #include "tokenid_kit.h"
34 #endif
35 #endif
36
37 namespace OHOS {
38 namespace AppManagerEts {
39 namespace {
40 constexpr const char* APP_MANAGER_SPACE_NAME = "L@ohos/app/ability/appManager/appManager;";
41 }
42
43 class EtsAppManager final {
44 public:
45 static void PreloadApplication(ani_env *env, ani_object callback, ani_string aniBundleName, ani_double aniUserId,
46 ani_enum_item aniMode, ani_object aniAppIndex);
47 static void GetRunningProcessInformation(ani_env *env, ani_object callback);
48 static void GetForegroundApplications(ani_env *env, ani_object callback);
49 static void GetRunningMultiAppInfo(ani_env *env, ani_string aniBundleName, ani_object callback);
50 static void GetRunningProcessInfoByBundleNameAndUserId(ani_env *env, ani_string aniBundleName,
51 ani_double aniUserId, ani_object callback);
52 static void GetRunningProcessInfoByBundleName(ani_env *env, ani_string aniBundleName, ani_object callback);
53 private:
54 static sptr<AppExecFwk::IAppMgr> GetAppManagerInstance();
55 #ifdef SUPPORT_SCREEN
56 static bool CheckCallerIsSystemApp();
57 #endif
58 static ani_double OnOnApplicationStateInner(
59 ani_env *env, ani_string type, ani_object observer, ani_object aniBundleNameList);
60 };
61
GetAppManagerInstance()62 sptr<AppExecFwk::IAppMgr> EtsAppManager::GetAppManagerInstance()
63 {
64 sptr<ISystemAbilityManager> systemAbilityManager =
65 OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
66 sptr<IRemoteObject> appObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
67 return iface_cast<AppExecFwk::IAppMgr>(appObject);
68 }
69
70 #ifdef SUPPORT_SCREEN
CheckCallerIsSystemApp()71 bool EtsAppManager::CheckCallerIsSystemApp()
72 {
73 auto selfToken = IPCSkeleton::GetSelfTokenID();
74 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken);
75 }
76 #endif
77
PreloadApplication(ani_env * env,ani_object callback,ani_string aniBundleName,ani_double aniUserId,ani_enum_item aniMode,ani_object aniAppIndex)78 void EtsAppManager::PreloadApplication(ani_env *env, ani_object callback, ani_string aniBundleName,
79 ani_double aniUserId, ani_enum_item aniMode, ani_object aniAppIndex)
80 {
81 TAG_LOGD(AAFwkTag::APPMGR, "PreloadApplication");
82 if (env == nullptr) {
83 TAG_LOGE(AAFwkTag::APPMGR, "env is null");
84 return;
85 }
86 std::string bundleName;
87 if (!AppExecFwk::GetStdString(env, aniBundleName, bundleName)) {
88 TAG_LOGE(AAFwkTag::APPMGR, "param bundlename err");
89 AppExecFwk::AsyncCallback(env, callback,
90 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
91 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)), nullptr);
92 return;
93 }
94 TAG_LOGD(AAFwkTag::APPMGR, "PreloadApplication userId:%{public}f, bundleName %{public}s",
95 aniUserId, bundleName.c_str());
96 int32_t userId = static_cast<int32_t>(aniUserId);
97
98 ani_int mode = 0;
99 if (!AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(env, aniMode, mode)) {
100 TAG_LOGE(AAFwkTag::APPMGR, "param mode err");
101 AppExecFwk::AsyncCallback(env, callback,
102 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
103 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)), nullptr);
104 return;
105 }
106
107 ani_status status = ANI_OK;
108 int32_t appIndex = 0;
109 ani_boolean isUndefined = false;
110 if ((status = env->Reference_IsUndefined(aniAppIndex, &isUndefined)) != ANI_OK) {
111 TAG_LOGE(AAFwkTag::APPMGR, "Failed to check undefined status : %{public}d", status);
112 return;
113 }
114 ani_double dval = 0.0;
115 if (!isUndefined) {
116 if ((status = env->Object_CallMethodByName_Double(aniAppIndex, "doubleValue", nullptr, &dval)) != ANI_OK) {
117 TAG_LOGE(AAFwkTag::APPMGR, "Object_CallMethodByName_Double status : %{public}d", status);
118 return;
119 }
120 TAG_LOGD(AAFwkTag::APPMGR, "aniAppIndex: %{public}f", dval);
121 appIndex = static_cast<int32_t>(dval);
122 }
123 TAG_LOGD(AAFwkTag::APPMGR, "PreloadApplication userId:%{public}d, mode:%{public}d, appIndex:%{public}d",
124 userId, mode, appIndex);
125 sptr<AppExecFwk::IAppMgr> appMgr = GetAppManagerInstance();
126 if (appMgr == nullptr) {
127 TAG_LOGE(AAFwkTag::APPMGR, "appManager null ptr");
128 AppExecFwk::AsyncCallback(env, callback,
129 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
130 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), nullptr);
131 return;
132 }
133 auto ret = appMgr->PreloadApplication(bundleName, userId, static_cast<AppExecFwk::PreloadMode>(mode), appIndex);
134 TAG_LOGD(AAFwkTag::APPMGR, "PreloadApplication ret %{public}d", ret);
135
136 AppExecFwk::AsyncCallback(env, callback,
137 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, static_cast<int32_t>(ret)), nullptr);
138 TAG_LOGD(AAFwkTag::APPMGR, "PreloadApplication END");
139 }
140
GetRunningProcessInformation(ani_env * env,ani_object callback)141 void EtsAppManager::GetRunningProcessInformation(ani_env *env, ani_object callback)
142 {
143 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningProcessInformation called");
144 if (env == nullptr) {
145 TAG_LOGE(AAFwkTag::APPMGR, "env null ptr");
146 return;
147 }
148 ani_object emptyArray = CreateEmptyAniArray(env);
149 sptr<AppExecFwk::IAppMgr> appMgr = GetAppManagerInstance();
150 if (appMgr == nullptr) {
151 TAG_LOGE(AAFwkTag::APPMGR, "appManager null ptr");
152 AppExecFwk::AsyncCallback(env, callback,
153 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
154 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyArray);
155 return;
156 }
157 std::vector<AppExecFwk::RunningProcessInfo> infos;
158 auto ret = appMgr->GetAllRunningProcesses(infos);
159 TAG_LOGD(AAFwkTag::APPMGR, "GetAllRunningProcesses ret:%{public}d, size:%{public}zu", ret, infos.size());
160 if (ret != ERR_OK) {
161 AppExecFwk::AsyncCallback(env, callback,
162 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, static_cast<int32_t>(ret)), emptyArray);
163 return;
164 }
165 ani_object aniInfosRef = CreateRunningProcessInfoArray(env, infos);
166 if (aniInfosRef == nullptr) {
167 AppExecFwk::AsyncCallback(env, callback,
168 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
169 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyArray);
170 } else {
171 AppExecFwk::AsyncCallback(env, callback,
172 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, static_cast<int32_t>(ret)), aniInfosRef);
173 }
174 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningProcessInformation finished");
175 }
176
GetForegroundApplications(ani_env * env,ani_object callback)177 void EtsAppManager::GetForegroundApplications(ani_env *env, ani_object callback)
178 {
179 TAG_LOGD(AAFwkTag::APPMGR, "GetForegroundApplications called");
180 if (env == nullptr) {
181 TAG_LOGE(AAFwkTag::APPMGR, "env null ptr");
182 return;
183 }
184 ani_object emptyArray = CreateEmptyAniArray(env);
185 auto appManager = GetAppManagerInstance();
186 if (appManager == nullptr) {
187 TAG_LOGE(AAFwkTag::APPMGR, "appManager null ptr");
188 AppExecFwk::AsyncCallback(env, callback,
189 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
190 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyArray);
191 return;
192 }
193 std::vector<AppExecFwk::AppStateData> appStateData;
194 int32_t ret = appManager->GetForegroundApplications(appStateData);
195 TAG_LOGD(AAFwkTag::APPMGR, "GetForegroundApplications ret:%{public}d, size:%{public}zu", ret, appStateData.size());
196 if (ret != ERR_OK) {
197 AppExecFwk::AsyncCallback(env, callback,
198 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, static_cast<int32_t>(ret)), emptyArray);
199 return;
200 }
201 ani_object appStateDataObj = CreateAppStateDataArray(env, appStateData);
202 if (appStateDataObj == nullptr) {
203 AppExecFwk::AsyncCallback(env, callback,
204 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
205 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyArray);
206 } else {
207 AppExecFwk::AsyncCallback(env, callback,
208 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, static_cast<int32_t>(ret)),
209 appStateDataObj);
210 }
211 TAG_LOGD(AAFwkTag::APPMGR, "GetForegroundApplications end");
212 }
213
GetRunningMultiAppInfo(ani_env * env,ani_string aniBundleName,ani_object callback)214 void EtsAppManager::GetRunningMultiAppInfo(ani_env *env, ani_string aniBundleName, ani_object callback)
215 {
216 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningMultiAppInfo called");
217 if (env == nullptr) {
218 TAG_LOGE(AAFwkTag::APPMGR, "env null ptr");
219 return;
220 }
221 ani_object emptyMultiAppInfo = CreateEmptyMultiAppInfo(env);
222 #ifdef SUPPORT_SCREEN
223 if (!CheckCallerIsSystemApp()) {
224 TAG_LOGE(AAFwkTag::APPMGR, "Non-system app");
225 AppExecFwk::AsyncCallback(env, callback,
226 AbilityRuntime::EtsErrorUtil::CreateError(
227 env, AbilityRuntime::AbilityErrorCode::ERROR_CODE_NOT_SYSTEM_APP), emptyMultiAppInfo);
228 return;
229 }
230 #endif
231 std::string bundleName;
232 if (!AppExecFwk::GetStdString(env, aniBundleName, bundleName) || bundleName.empty()) {
233 TAG_LOGE(AAFwkTag::APPMGR, "GetStdString Failed");
234 AppExecFwk::AsyncCallback(env, callback,
235 AbilityRuntime::EtsErrorUtil::CreateError(env,
236 static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM),
237 "Parse param bundleName failed, must be a string."), emptyMultiAppInfo);
238 return;
239 }
240 auto appManager = GetAppManagerInstance();
241 if (appManager == nullptr) {
242 TAG_LOGE(AAFwkTag::APPMGR, "appManager nullptr");
243 AppExecFwk::AsyncCallback(env, callback,
244 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
245 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyMultiAppInfo);
246 return;
247 }
248 AppExecFwk::RunningMultiAppInfo info;
249 int32_t innerErrorCode = ERR_OK;
250 innerErrorCode = appManager->GetRunningMultiAppInfoByBundleName(bundleName, info);
251 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningMultiAppInfoByBundleName ret: %{public}d", innerErrorCode);
252 if (innerErrorCode != ERR_OK) {
253 AppExecFwk::AsyncCallback(env, callback,
254 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, innerErrorCode), emptyMultiAppInfo);
255 return;
256 }
257 ani_object appinfoObj = WrapRunningMultiAppInfo(env, info);
258 if (appinfoObj == nullptr) {
259 AppExecFwk::AsyncCallback(env, callback,
260 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
261 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyMultiAppInfo);
262 } else {
263 AppExecFwk::AsyncCallback(
264 env, callback, AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, innerErrorCode), appinfoObj);
265 }
266 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningMultiAppInfo end");
267 }
268
GetRunningProcessInfoByBundleNameAndUserId(ani_env * env,ani_string aniBundleName,ani_double aniUserId,ani_object callback)269 void EtsAppManager::GetRunningProcessInfoByBundleNameAndUserId(
270 ani_env *env, ani_string aniBundleName, ani_double aniUserId, ani_object callback)
271 {
272 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningProcessInfoByBundleNameAndUserId called");
273 if (env == nullptr) {
274 TAG_LOGE(AAFwkTag::APPMGR, "env null ptr");
275 return;
276 }
277 ani_object emptyArray = CreateEmptyAniArray(env);
278 if (aniBundleName == nullptr) {
279 TAG_LOGE(AAFwkTag::APPMGR, "aniBundleName null ptr");
280 AppExecFwk::AsyncCallback(env, callback,
281 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
282 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)), emptyArray);
283 return;
284 }
285 std::string bundleName;
286 if (!AppExecFwk::GetStdString(env, aniBundleName, bundleName)) {
287 TAG_LOGE(AAFwkTag::APPMGR, "GetStdString Failed");
288 AppExecFwk::AsyncCallback(env, callback,
289 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
290 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INVALID_PARAM)), emptyArray);
291 return;
292 }
293 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningProcessInfoByBundleNameAndUserId userid:%{public}f", aniUserId);
294 int32_t userId = static_cast<int32_t>(aniUserId);
295 auto appManager = GetAppManagerInstance();
296 if (appManager == nullptr) {
297 TAG_LOGE(AAFwkTag::APPMGR, "appManager nullptr");
298 AppExecFwk::AsyncCallback(env, callback,
299 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
300 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyArray);
301 return;
302 }
303 std::vector<AppExecFwk::RunningProcessInfo> infos;
304 int32_t ret = appManager->GetRunningProcessInformation(bundleName, userId, infos);
305 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningProcessInformation ret: %{public}d, size:%{public}zu", ret, infos.size());
306 if (ret != ERR_OK) {
307 AppExecFwk::AsyncCallback(env, callback,
308 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, static_cast<int32_t>(ret)), emptyArray);
309 return;
310 }
311 ani_object aniInfos = CreateRunningProcessInfoArray(env, infos);
312 if (aniInfos == nullptr) {
313 AppExecFwk::AsyncCallback(env, callback,
314 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(
315 env, static_cast<int32_t>(AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER)), emptyArray);
316 } else {
317 AppExecFwk::AsyncCallback(env, callback,
318 AbilityRuntime::EtsErrorUtil::CreateErrorByNativeErr(env, static_cast<int32_t>(ret)), aniInfos);
319 }
320 TAG_LOGD(AAFwkTag::APPMGR, "GetRunningProcessInfoByBundleNameAndUserId finished");
321 }
322
GetRunningProcessInfoByBundleName(ani_env * env,ani_string aniBundleName,ani_object callback)323 void EtsAppManager::GetRunningProcessInfoByBundleName(ani_env *env, ani_string aniBundleName, ani_object callback)
324 {
325 int userId = IPCSkeleton::GetCallingUid() / AppExecFwk::Constants::BASE_USER_RANGE;
326 GetRunningProcessInfoByBundleNameAndUserId(env, aniBundleName, static_cast<double>(userId), callback);
327 }
328
EtsAppManagerRegistryInit(ani_env * env)329 void EtsAppManagerRegistryInit(ani_env *env)
330 {
331 TAG_LOGD(AAFwkTag::APPMGR, "EtsAppManagerRegistryInit call");
332 if (env == nullptr) {
333 TAG_LOGE(AAFwkTag::APPMGR, "env null ptr");
334 return;
335 }
336 ani_status status = ANI_ERROR;
337 if (env->ResetError() != ANI_OK) {
338 TAG_LOGE(AAFwkTag::APPMGR, "ResetError failed");
339 }
340 ani_namespace ns;
341 status = env->FindNamespace(APP_MANAGER_SPACE_NAME, &ns);
342 if (status != ANI_OK) {
343 TAG_LOGE(AAFwkTag::APPMGR, "FindNamespace appManager failed status : %{public}d", status);
344 return;
345 }
346 std::array kitFunctions = {
347 ani_native_function{
348 "nativePreloadApplication", nullptr, reinterpret_cast<void *>(EtsAppManager::PreloadApplication)},
349 ani_native_function{"nativeGetRunningProcessInformation",
350 nullptr,
351 reinterpret_cast<void *>(EtsAppManager::GetRunningProcessInformation)},
352 ani_native_function{"nativeGetForegroundApplications",
353 nullptr,
354 reinterpret_cast<void *>(EtsAppManager::GetForegroundApplications)},
355 ani_native_function{
356 "nativeGetRunningMultiAppInfo", nullptr, reinterpret_cast<void *>(EtsAppManager::GetRunningMultiAppInfo)},
357 ani_native_function{"nativeGetRunningProcessInfoByBundleName",
358 nullptr,
359 reinterpret_cast<void *>(EtsAppManager::GetRunningProcessInfoByBundleName)},
360 ani_native_function{"nativeGetRunningProcessInfoByBundleNameAndUserId",
361 nullptr,
362 reinterpret_cast<void *>(EtsAppManager::GetRunningProcessInfoByBundleNameAndUserId)}};
363 status = env->Namespace_BindNativeFunctions(ns, kitFunctions.data(), kitFunctions.size());
364 if (status != ANI_OK) {
365 TAG_LOGE(AAFwkTag::APPMGR, "Namespace_BindNativeFunctions failed status : %{public}d", status);
366 }
367 if (env->ResetError() != ANI_OK) {
368 TAG_LOGE(AAFwkTag::APPMGR, "ResetError failed");
369 }
370 TAG_LOGD(AAFwkTag::APPMGR, "EtsAppManagerRegistryInit end");
371 }
372
373 extern "C" {
ANI_Constructor(ani_vm * vm,uint32_t * result)374 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
375 {
376 TAG_LOGD(AAFwkTag::APPMGR, "in AppManagerEts.ANI_Constructor");
377 if (vm == nullptr || result == nullptr) {
378 TAG_LOGE(AAFwkTag::APPMGR, "null vm or result");
379 return ANI_INVALID_ARGS;
380 }
381
382 ani_env *env = nullptr;
383 ani_status status = ANI_ERROR;
384 status = vm->GetEnv(ANI_VERSION_1, &env);
385 if (status != ANI_OK) {
386 TAG_LOGE(AAFwkTag::APPMGR, "GetEnv failed, status=%{public}d", status);
387 return ANI_NOT_FOUND;
388 }
389 EtsAppManagerRegistryInit(env);
390 *result = ANI_VERSION_1;
391 TAG_LOGD(AAFwkTag::APPMGR, "AppManagerEts.ANI_Constructor finished");
392 return ANI_OK;
393 }
394 } // extern "C"
395 } // namespace AppManagerEts
396 } // namespace OHOS