• 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_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