• 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 <cmath>
17 #include <cstring>
18 #include <iostream>
19 #include <limits>
20 #include <mutex>
21 #include <shared_mutex>
22 #include <string>
23 #include <unistd.h>
24 #include <unordered_map>
25 #include <vector>
26 
27 #include "ani_bundle_manager.h"
28 #include "ani_common_want.h"
29 #include <ani_signature_builder.h>
30 #include "app_log_wrapper.h"
31 #include "bundle_errors.h"
32 #include "bundle_manager_helper.h"
33 #include "bundle_mgr_client.h"
34 #include "bundle_mgr_interface.h"
35 #include "bundle_mgr_proxy.h"
36 #include "business_error_ani.h"
37 #include "common_fun_ani.h"
38 #include "common_func.h"
39 #include "enum_util.h"
40 #include "ipc_skeleton.h"
41 #include "napi_constants.h"
42 
43 namespace OHOS {
44 namespace AppExecFwk {
45 namespace {
46 static ani_vm* g_vm;
47 static std::mutex g_aniClearCacheListenerMutex;
48 static std::shared_ptr<ANIClearCacheListener> g_aniClearCacheListener;
49 static std::shared_mutex g_aniCacheMutex;
50 static std::unordered_map<ANIQuery, ani_ref, ANIQueryHash> g_aniCache;
51 static std::string g_aniOwnBundleName;
52 static std::mutex g_aniOwnBundleNameMutex;
53 constexpr int32_t EMPTY_USER_ID = -500;
54 } // namespace
55 
CheckToCache(ani_env * env,const int32_t uid,const int32_t callingUid,const ANIQuery & query,ani_object aniObject)56 static void CheckToCache(
57     ani_env* env, const int32_t uid, const int32_t callingUid, const ANIQuery& query, ani_object aniObject)
58 {
59     RETURN_IF_NULL(aniObject);
60     if (uid != callingUid) {
61         return;
62     }
63 
64     ani_ref info = nullptr;
65     ani_status status = env->GlobalReference_Create(aniObject, &info);
66     if (status == ANI_OK) {
67         std::unique_lock<std::shared_mutex> lock(g_aniCacheMutex);
68         g_aniCache[query] = info;
69     }
70 }
71 
72 template <typename T>
CheckInfoCache(ani_env * env,const ANIQuery & query,const OHOS::AAFwk::Want & want,std::vector<T> infos,ani_object aniObject)73 static void CheckInfoCache(ani_env* env, const ANIQuery& query,
74     const OHOS::AAFwk::Want& want, std::vector<T> infos, ani_object aniObject)
75 {
76     RETURN_IF_NULL(aniObject);
77     ElementName element = want.GetElement();
78     if (element.GetBundleName().empty() || element.GetAbilityName().empty()) {
79         return;
80     }
81 
82     if (infos.size() != EXPLICIT_QUERY_RESULT_LEN || infos[0].uid != IPCSkeleton::GetCallingUid()) {
83         return;
84     }
85 
86     ani_ref cacheInfo = nullptr;
87     ani_status status = env->GlobalReference_Create(aniObject, &cacheInfo);
88     if (status == ANI_OK) {
89         std::unique_lock<std::shared_mutex> lock(g_aniCacheMutex);
90         g_aniCache[query] = cacheInfo;
91     }
92 }
93 
CheckBatchAbilityInfoCache(ani_env * env,const ANIQuery & query,const std::vector<OHOS::AAFwk::Want> & wants,std::vector<AbilityInfo> abilityInfos,ani_object aniObject)94 static void CheckBatchAbilityInfoCache(ani_env* env, const ANIQuery &query,
95     const std::vector<OHOS::AAFwk::Want> &wants, std::vector<AbilityInfo> abilityInfos, ani_object aniObject)
96 {
97     RETURN_IF_NULL(aniObject);
98     for (size_t i = 0; i < wants.size(); i++) {
99         ElementName element = wants[i].GetElement();
100         if (element.GetBundleName().empty() || element.GetAbilityName().empty()) {
101             return;
102         }
103     }
104 
105     uint32_t explicitQueryResultLen = 1;
106     if (abilityInfos.size() != explicitQueryResultLen ||
107         (abilityInfos.size() > 0 && abilityInfos[0].uid != IPCSkeleton::GetCallingUid())) {
108         return;
109     }
110 
111     ani_ref cacheInfo = nullptr;
112     ani_status status = env->GlobalReference_Create(aniObject, &cacheInfo);
113     if (status == ANI_OK) {
114         std::unique_lock<std::shared_mutex> lock(g_aniCacheMutex);
115         g_aniCache[query] = cacheInfo;
116     }
117 }
118 
ParseAniWant(ani_env * env,ani_object aniWant,OHOS::AAFwk::Want & want)119 static bool ParseAniWant(ani_env* env, ani_object aniWant, OHOS::AAFwk::Want& want)
120 {
121     RETURN_FALSE_IF_NULL(aniWant);
122     ani_string string = nullptr;
123     std::string bundleName;
124     std::string abilityName;
125     std::string moduleName;
126 
127     if (CommonFunAni::CallGetterOptional(env, aniWant, BUNDLE_NAME, &string)) {
128         bundleName = CommonFunAni::AniStrToString(env, string);
129     }
130     if (CommonFunAni::CallGetterOptional(env, aniWant, Constants::ABILITY_NAME, &string)) {
131         abilityName = CommonFunAni::AniStrToString(env, string);
132     }
133     if (CommonFunAni::CallGetterOptional(env, aniWant, MODULE_NAME, &string)) {
134         moduleName = CommonFunAni::AniStrToString(env, string);
135     }
136     if (!bundleName.empty() && !abilityName.empty()) {
137         ElementName elementName("", bundleName, abilityName, moduleName);
138         want.SetElement(elementName);
139         return true;
140     }
141     if (!UnwrapWant(env, aniWant, want)) {
142         APP_LOGW("parse want failed");
143         return false;
144     }
145     bool isExplicit = !want.GetBundle().empty() && !want.GetElement().GetAbilityName().empty();
146     if (!isExplicit && want.GetAction().empty() && want.GetEntities().empty() &&
147         want.GetUriString().empty() && want.GetType().empty() && want.GetStringParam(LINK_FEATURE).empty()) {
148         APP_LOGW("implicit params all empty");
149         return false;
150     }
151     return true;
152 }
153 
ParseAniWantList(ani_env * env,ani_object aniWants,std::vector<OHOS::AAFwk::Want> & wants)154 static bool ParseAniWantList(ani_env* env, ani_object aniWants, std::vector<OHOS::AAFwk::Want> &wants)
155 {
156     RETURN_FALSE_IF_NULL(aniWants);
157     return CommonFunAni::AniArrayForeach(env, aniWants, [env, &wants](ani_object aniWantItem) {
158         OHOS::AAFwk::Want want;
159         bool result = UnwrapWant(env, aniWantItem, want);
160         if (!result) {
161             wants.clear();
162             return false;
163         }
164         bool isExplicit = !want.GetBundle().empty() && !want.GetElement().GetAbilityName().empty();
165         if (!isExplicit && want.GetAction().empty() && want.GetEntities().empty() &&
166             want.GetUriString().empty() && want.GetType().empty() && want.GetStringParam(LINK_FEATURE).empty()) {
167             APP_LOGW("implicit params all empty of want");
168             return true;
169         }
170         wants.emplace_back(want);
171 
172         return true;
173     });
174 }
175 
GetBundleInfoForSelfNative(ani_env * env,ani_double aniBundleFlags,ani_boolean aniIsSync)176 static ani_object GetBundleInfoForSelfNative(ani_env* env, ani_double aniBundleFlags, ani_boolean aniIsSync)
177 {
178     APP_LOGD("ani GetBundleInfoForSelf called");
179     int32_t bundleFlags = 0;
180     if (!CommonFunAni::TryCastDoubleTo(aniBundleFlags, &bundleFlags)) {
181         APP_LOGE("Cast aniBundleFlags failed");
182         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_FLAGS, TYPE_NUMBER);
183         return nullptr;
184     }
185     auto iBundleMgr = CommonFunc::GetBundleMgr();
186     if (iBundleMgr == nullptr) {
187         APP_LOGE("GetBundleMgr failed");
188         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
189         return nullptr;
190     }
191     const auto uid = IPCSkeleton::GetCallingUid();
192     std::string bundleName = std::to_string(uid);
193     int32_t userId = uid / Constants::BASE_USER_RANGE;
194     const ANIQuery query(bundleName, GET_BUNDLE_INFO, bundleFlags, userId);
195     if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlags)) {
196         std::shared_lock<std::shared_mutex> lock(g_aniCacheMutex);
197         auto item = g_aniCache.find(query);
198         if (item != g_aniCache.end()) {
199             return reinterpret_cast<ani_object>(item->second);
200         }
201     }
202 
203     BundleInfo bundleInfo;
204     ErrCode ret = iBundleMgr->GetBundleInfoForSelf(bundleFlags, bundleInfo);
205     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
206     if (ret != ERR_OK) {
207         APP_LOGE("GetBundleInfoForSelf failed ret: %{public}d", ret);
208         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
209             isSync ? GET_BUNDLE_INFO_FOR_SELF_SYNC : GET_BUNDLE_INFO,
210             isSync ? BUNDLE_PERMISSIONS : Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
211         return nullptr;
212     }
213 
214     ani_object objectBundleInfo = CommonFunAni::ConvertBundleInfo(env, bundleInfo, bundleFlags);
215     if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlags)) {
216         CheckToCache(env, bundleInfo.uid, uid, query, objectBundleInfo);
217     }
218 
219     return objectBundleInfo;
220 }
221 
GetBundleInfoNative(ani_env * env,ani_string aniBundleName,ani_double aniBundleFlags,ani_double aniUserId,ani_boolean aniIsSync)222 static ani_object GetBundleInfoNative(ani_env* env,
223     ani_string aniBundleName, ani_double aniBundleFlags, ani_double aniUserId, ani_boolean aniIsSync)
224 {
225     APP_LOGD("ani GetBundleInfo called");
226     int32_t bundleFlags = 0;
227     if (!CommonFunAni::TryCastDoubleTo(aniBundleFlags, &bundleFlags)) {
228         APP_LOGE("Cast aniBundleFlags failed");
229         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_FLAGS, TYPE_NUMBER);
230         return nullptr;
231     }
232     int32_t userId = EMPTY_USER_ID;
233     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
234         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
235     }
236     int32_t callingUid = IPCSkeleton::GetCallingUid();
237     if (userId == EMPTY_USER_ID) {
238         userId = callingUid / Constants::BASE_USER_RANGE;
239     }
240     std::string bundleName;
241     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
242         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
243         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
244         return nullptr;
245     }
246     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
247     if (isSync && bundleName.size() == 0) {
248         BusinessErrorAni::ThrowCommonError(
249             env, ERROR_BUNDLE_NOT_EXIST, GET_BUNDLE_INFO_SYNC, BUNDLE_PERMISSIONS);
250         return nullptr;
251     }
252 
253     ANIQuery query(bundleName, GET_BUNDLE_INFO, bundleFlags, userId);
254     if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlags)) {
255         std::shared_lock<std::shared_mutex> lock(g_aniCacheMutex);
256         auto item = g_aniCache.find(query);
257         if (item != g_aniCache.end()) {
258             APP_LOGD("Get bundle info from global cache.");
259             return reinterpret_cast<ani_object>(item->second);
260         }
261     }
262 
263     auto iBundleMgr = CommonFunc::GetBundleMgr();
264     if (iBundleMgr == nullptr) {
265         APP_LOGE("Get bundle mgr failed");
266         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
267         return nullptr;
268     }
269     BundleInfo bundleInfo;
270     ErrCode ret = iBundleMgr->GetBundleInfoV9(bundleName, bundleFlags, bundleInfo, userId);
271     if (ret != ERR_OK) {
272         APP_LOGE("GetBundleInfoV9 failed ret: %{public}d", ret);
273         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
274             isSync ? GET_BUNDLE_INFO_SYNC : GET_BUNDLE_INFO,
275             isSync ? BUNDLE_PERMISSIONS : Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
276         return nullptr;
277     }
278 
279     ani_object objectBundleInfo = CommonFunAni::ConvertBundleInfo(env, bundleInfo, bundleFlags);
280     if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlags)) {
281         CheckToCache(env, bundleInfo.uid, callingUid, query, objectBundleInfo);
282     }
283 
284     return objectBundleInfo;
285 }
286 
GetApplicationInfoNative(ani_env * env,ani_string aniBundleName,ani_double aniApplicationFlags,ani_double aniUserId,ani_boolean aniIsSync)287 static ani_object GetApplicationInfoNative(ani_env* env,
288     ani_string aniBundleName, ani_double aniApplicationFlags, ani_double aniUserId, ani_boolean aniIsSync)
289 {
290     APP_LOGD("ani GetApplicationInfo called");
291     int32_t applicationFlags = 0;
292     if (!CommonFunAni::TryCastDoubleTo(aniApplicationFlags, &applicationFlags)) {
293         APP_LOGE("Cast aniApplicationFlags failed");
294         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, APP_FLAGS, TYPE_NUMBER);
295         return nullptr;
296     }
297     int32_t userId = EMPTY_USER_ID;
298     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
299         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
300     }
301     std::string bundleName;
302     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
303         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
304         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
305         return nullptr;
306     }
307     int32_t callingUid = IPCSkeleton::GetCallingUid();
308     if (userId == EMPTY_USER_ID) {
309         userId = callingUid / Constants::BASE_USER_RANGE;
310     }
311 
312     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
313     if (isSync && bundleName.size() == 0) {
314         BusinessErrorAni::ThrowCommonError(
315             env, ERROR_BUNDLE_NOT_EXIST, GET_APPLICATION_INFO_SYNC, BUNDLE_PERMISSIONS);
316         return nullptr;
317     }
318 
319     const ANIQuery query(bundleName, GET_APPLICATION_INFO, applicationFlags, userId);
320     {
321         std::shared_lock<std::shared_mutex> lock(g_aniCacheMutex);
322         auto item = g_aniCache.find(query);
323         if (item != g_aniCache.end()) {
324             return reinterpret_cast<ani_object>(item->second);
325         }
326     }
327 
328     auto iBundleMgr = CommonFunc::GetBundleMgr();
329     if (iBundleMgr == nullptr) {
330         APP_LOGE("nullptr iBundleMgr");
331         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
332         return nullptr;
333     }
334     ApplicationInfo appInfo;
335     ErrCode ret = iBundleMgr->GetApplicationInfoV9(bundleName, applicationFlags, userId, appInfo);
336     if (ret != ERR_OK) {
337         APP_LOGE("GetApplicationInfoV9 failed ret: %{public}d,userId: %{public}d", ret, userId);
338         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
339             isSync ? GET_APPLICATION_INFO_SYNC : GET_APPLICATION_INFO,
340             isSync ? BUNDLE_PERMISSIONS : Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
341         return nullptr;
342     }
343 
344     ani_object objectApplicationInfo = CommonFunAni::ConvertApplicationInfo(env, appInfo);
345     CheckToCache(env, appInfo.uid, callingUid, query, objectApplicationInfo);
346 
347     return objectApplicationInfo;
348 }
349 
GetAllBundleInfoNative(ani_env * env,ani_double aniBundleFlags,ani_double aniUserId)350 static ani_object GetAllBundleInfoNative(ani_env* env, ani_double aniBundleFlags, ani_double aniUserId)
351 {
352     APP_LOGD("ani GetAllBundleInfo called");
353     int32_t bundleFlags = 0;
354     if (!CommonFunAni::TryCastDoubleTo(aniBundleFlags, &bundleFlags)) {
355         APP_LOGE("Cast aniBundleFlags failed");
356         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_FLAGS, TYPE_NUMBER);
357         return nullptr;
358     }
359     int32_t userId = EMPTY_USER_ID;
360     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
361         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
362     }
363     if (userId == EMPTY_USER_ID) {
364         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
365     }
366 
367     auto iBundleMgr = CommonFunc::GetBundleMgr();
368     if (iBundleMgr == nullptr) {
369         APP_LOGE("Get bundle mgr failed");
370         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
371         return nullptr;
372     }
373     std::vector<BundleInfo> bundleInfos;
374     ErrCode ret = iBundleMgr->GetBundleInfosV9(bundleFlags, bundleInfos, userId);
375     if (ret != ERR_OK) {
376         APP_LOGE("GetBundleInfosV9 failed ret: %{public}d", ret);
377         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret), GET_BUNDLE_INFOS,
378             Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST);
379         return nullptr;
380     }
381     APP_LOGI("GetBundleInfosV9 ret: %{public}d, bundleInfos size: %{public}zu", ret, bundleInfos.size());
382 
383     return CommonFunAni::ConvertAniArray(env, bundleInfos, CommonFunAni::ConvertBundleInfo, bundleFlags);
384 }
385 
GetAllApplicationInfoNative(ani_env * env,ani_double aniApplicationFlags,ani_double aniUserId)386 static ani_object GetAllApplicationInfoNative(ani_env* env, ani_double aniApplicationFlags, ani_double aniUserId)
387 {
388     APP_LOGD("ani GetAllApplicationInfo called");
389     int32_t applicationFlags = 0;
390     if (!CommonFunAni::TryCastDoubleTo(aniApplicationFlags, &applicationFlags)) {
391         APP_LOGE("Cast aniApplicationFlags failed");
392         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, APP_FLAGS, TYPE_NUMBER);
393         return nullptr;
394     }
395     int32_t userId = EMPTY_USER_ID;
396     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
397         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
398     }
399 
400     if (userId == EMPTY_USER_ID) {
401         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
402     }
403 
404     auto iBundleMgr = CommonFunc::GetBundleMgr();
405     if (iBundleMgr == nullptr) {
406         APP_LOGE("nullptr iBundleMgr");
407         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
408         return nullptr;
409     }
410     std::vector<ApplicationInfo> appInfos;
411     ErrCode ret = iBundleMgr->GetApplicationInfosV9(applicationFlags, userId, appInfos);
412     if (ret != ERR_OK) {
413         APP_LOGE("GetApplicationInfosV9 failed ret: %{public}d", ret);
414         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret), GET_APPLICATION_INFOS,
415             Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST);
416         return nullptr;
417     }
418     APP_LOGI("applicationInfos size: %{public}zu", appInfos.size());
419 
420     return CommonFunAni::ConvertAniArray(env, appInfos, CommonFunAni::ConvertApplicationInfo);
421 }
422 
IsApplicationEnabledNative(ani_env * env,ani_string aniBundleName,ani_double aniAppIndex,ani_boolean aniIsSync)423 static ani_boolean IsApplicationEnabledNative(ani_env* env,
424     ani_string aniBundleName, ani_double aniAppIndex, ani_boolean aniIsSync)
425 {
426     APP_LOGD("ani IsApplicationEnabled called");
427     bool isEnable = false;
428     std::string bundleName;
429     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
430         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
431         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
432         return isEnable;
433     }
434     int32_t appIndex = 0;
435     if (!CommonFunAni::TryCastDoubleTo(aniAppIndex, &appIndex)) {
436         APP_LOGE("Cast aniAppIndex failed");
437         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, TYPE_NUMBER);
438         return isEnable;
439     }
440     auto iBundleMgr = CommonFunc::GetBundleMgr();
441     if (iBundleMgr == nullptr) {
442         APP_LOGE("GetBundleMgr failed");
443         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
444         return isEnable;
445     }
446     if (bundleName.empty()) {
447         APP_LOGW("bundleName is empty");
448         BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_BUNDLENAME_EMPTY_ERROR);
449         return isEnable;
450     }
451     ErrCode ret = ERR_OK;
452     if (appIndex != 0) {
453         ret = iBundleMgr->IsCloneApplicationEnabled(bundleName, appIndex, isEnable);
454     } else {
455         ret = iBundleMgr->IsApplicationEnabled(bundleName, isEnable);
456     }
457     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
458     if (ret != ERR_OK) {
459         APP_LOGE("IsCloneApplicationEnabled failed ret: %{public}d", ret);
460         BusinessErrorAni::ThrowCommonError(
461             env, CommonFunc::ConvertErrCode(ret), isSync ? IS_APPLICATION_ENABLED_SYNC : "", "");
462     }
463     return isEnable;
464 }
465 
QueryAbilityInfoSyncNative(ani_env * env,ani_object aniWant,ani_double aniAbilityFlags,ani_double aniUserId,ani_boolean aniIsSync)466 static ani_object QueryAbilityInfoSyncNative(ani_env* env,
467     ani_object aniWant, ani_double aniAbilityFlags, ani_double aniUserId, ani_boolean aniIsSync)
468 {
469     APP_LOGD("ani QueryAbilityInfoSync called");
470     OHOS::AAFwk::Want want;
471     int32_t abilityFlags = 0;
472     int32_t userId = EMPTY_USER_ID;
473     if (!ParseAniWant(env, aniWant, want)) {
474         APP_LOGE("ParseAniWant failed");
475         BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, INVALID_WANT_ERROR);
476         return nullptr;
477     }
478     if (!CommonFunAni::TryCastDoubleTo(aniAbilityFlags, &abilityFlags)) {
479         APP_LOGE("Cast aniAbilityFlags failed");
480         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, ABILITY_FLAGS, TYPE_NUMBER);
481         return nullptr;
482     }
483     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
484         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
485     }
486 
487     if (userId == EMPTY_USER_ID) {
488         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
489     }
490     const ANIQuery query(want.ToString(), QUERY_ABILITY_INFOS_SYNC, abilityFlags, userId);
491     {
492         std::shared_lock<std::shared_mutex> lock(g_aniCacheMutex);
493         auto item = g_aniCache.find(query);
494         if (item != g_aniCache.end()) {
495             return reinterpret_cast<ani_object>(item->second);
496         }
497     }
498 
499     auto iBundleMgr = CommonFunc::GetBundleMgr();
500     if (iBundleMgr == nullptr) {
501         APP_LOGE("GetBundleMgr failed");
502         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
503         return nullptr;
504     }
505     std::vector<AbilityInfo> abilityInfos;
506     ErrCode ret = iBundleMgr->QueryAbilityInfosV9(want, abilityFlags, userId, abilityInfos);
507     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
508     if (ret != ERR_OK) {
509         APP_LOGE("QueryAbilityInfosV9 failed ret: %{public}d", ret);
510         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
511             isSync ? QUERY_ABILITY_INFOS_SYNC : QUERY_ABILITY_INFOS, BUNDLE_PERMISSIONS);
512         return nullptr;
513     }
514     ani_object aniAbilityInfos =
515         CommonFunAni::ConvertAniArray(env, abilityInfos, CommonFunAni::ConvertAbilityInfo);
516     CheckInfoCache(env, query, want, abilityInfos, aniAbilityInfos);
517     return aniAbilityInfos;
518 }
519 
GetAppCloneIdentityNative(ani_env * env,ani_double aniUid)520 static ani_object GetAppCloneIdentityNative(ani_env* env, ani_double aniUid)
521 {
522     APP_LOGD("ani GetAppCloneIdentity called");
523     int32_t uid = 0;
524     if (!CommonFunAni::TryCastDoubleTo(aniUid, &uid)) {
525         APP_LOGE("Cast aniUid failed");
526         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, Constants::UID, TYPE_NUMBER);
527         return nullptr;
528     }
529 
530     bool queryOwn = (uid == IPCSkeleton::GetCallingUid());
531     std::string bundleName;
532     int32_t appIndex = 0;
533     if (queryOwn) {
534         std::lock_guard<std::mutex> lock(g_aniOwnBundleNameMutex);
535         if (!g_aniOwnBundleName.empty()) {
536             APP_LOGD("ani query own bundleName and appIndex, has cache, no need to query from host");
537             CommonFunc::GetBundleNameAndIndexByName(g_aniOwnBundleName, bundleName, appIndex);
538             return CommonFunAni::ConvertAppCloneIdentity(env, bundleName, appIndex);
539         }
540     }
541 
542     ErrCode ret = BundleManagerHelper::InnerGetAppCloneIdentity(uid, bundleName, appIndex);
543     if (ret != ERR_OK) {
544         APP_LOGE("GetNameAndIndexForUid failed ret: %{public}d", ret);
545         BusinessErrorAni::ThrowCommonError(env, ret, GET_APP_CLONE_IDENTITY, APP_CLONE_IDENTITY_PERMISSIONS);
546         return nullptr;
547     }
548 
549     std::lock_guard<std::mutex> lock(g_aniOwnBundleNameMutex);
550     if (queryOwn && g_aniOwnBundleName.empty()) {
551         g_aniOwnBundleName = bundleName;
552         if (appIndex > 0) {
553             g_aniOwnBundleName = CommonFunc::GetCloneBundleIdKey(bundleName, appIndex);
554         }
555         APP_LOGD("ani put own bundleName = %{public}s to cache", g_aniOwnBundleName.c_str());
556     }
557     return CommonFunAni::ConvertAppCloneIdentity(env, bundleName, appIndex);
558 }
559 
GetAbilityLabelNative(ani_env * env,ani_string aniBundleName,ani_string aniModuleName,ani_string aniAbilityName,ani_boolean aniIsSync)560 static ani_string GetAbilityLabelNative(ani_env* env,
561     ani_string aniBundleName, ani_string aniModuleName, ani_string aniAbilityName, ani_boolean aniIsSync)
562 {
563 #ifdef GLOBAL_RESMGR_ENABLE
564     APP_LOGD("ani GetAbilityLabel called");
565     std::string bundleName;
566     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
567         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
568         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
569         return nullptr;
570     }
571     std::string moduleName;
572     if (!CommonFunAni::ParseString(env, aniModuleName, moduleName)) {
573         APP_LOGE("moduleName %{public}s invalid", moduleName.c_str());
574         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
575         return nullptr;
576     }
577     std::string abilityName;
578     if (!CommonFunAni::ParseString(env, aniAbilityName, abilityName)) {
579         APP_LOGE("abilityName %{public}s invalid", abilityName.c_str());
580         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, Constants::ABILITY_NAME, TYPE_STRING);
581         return nullptr;
582     }
583 
584     auto iBundleMgr = CommonFunc::GetBundleMgr();
585     if (iBundleMgr == nullptr) {
586         APP_LOGE("GetBundleMgr failed");
587         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
588         return nullptr;
589     }
590     std::string abilityLabel;
591     ErrCode ret = iBundleMgr->GetAbilityLabel(bundleName, moduleName, abilityName, abilityLabel);
592     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
593     if (ret != ERR_OK) {
594         APP_LOGE("GetAbilityLabel failed ret: %{public}d", ret);
595         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
596             isSync ? GET_ABILITY_LABEL_SYNC : GET_ABILITY_LABEL, BUNDLE_PERMISSIONS);
597         return nullptr;
598     }
599     ani_string aniAbilityLabel = nullptr;
600     if (!CommonFunAni::StringToAniStr(env, abilityLabel, aniAbilityLabel)) {
601         APP_LOGE("StringToAniStr failed");
602         return nullptr;
603     }
604     return aniAbilityLabel;
605 #else
606     APP_LOGW("SystemCapability.BundleManager.BundleFramework.Resource not supported");
607     BusinessErrorAni::ThrowCommonError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND, GET_ABILITY_LABEL, "");
608     return nullptr;
609 #endif
610 }
611 
GetLaunchWantForBundleNative(ani_env * env,ani_string aniBundleName,ani_double aniUserId,ani_boolean aniIsSync)612 static ani_object GetLaunchWantForBundleNative(ani_env* env,
613     ani_string aniBundleName, ani_double aniUserId, ani_boolean aniIsSync)
614 {
615     APP_LOGD("ani GetLaunchWantForBundle called");
616     std::string bundleName;
617     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
618         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
619         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
620         return nullptr;
621     }
622     int32_t userId = EMPTY_USER_ID;
623     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
624         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
625     }
626     if (userId == EMPTY_USER_ID) {
627         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
628     }
629 
630     auto iBundleMgr = CommonFunc::GetBundleMgr();
631     if (iBundleMgr == nullptr) {
632         APP_LOGE("GetBundleMgr failed");
633         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
634         return nullptr;
635     }
636     OHOS::AAFwk::Want want;
637     ErrCode ret = iBundleMgr->GetLaunchWantForBundle(bundleName, want, userId);
638     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
639     if (ret != ERR_OK) {
640         APP_LOGE("GetLaunchWantForBundle failed ret: %{public}d", ret);
641         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
642             isSync ? GET_LAUNCH_WANT_FOR_BUNDLE_SYNC : GET_LAUNCH_WANT_FOR_BUNDLE,
643             Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
644         return nullptr;
645     }
646     return CommonFunAni::ConvertWantInfo(env, want);
647 }
648 
GetAppCloneBundleInfoNative(ani_env * env,ani_string aniBundleName,ani_double aniAppIndex,ani_double aniBundleFlags,ani_double aniUserId)649 static ani_object GetAppCloneBundleInfoNative(ani_env* env, ani_string aniBundleName,
650     ani_double aniAppIndex, ani_double aniBundleFlags, ani_double aniUserId)
651 {
652     APP_LOGD("ani GetAppCloneBundleInfo called");
653     std::string bundleName;
654     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
655         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
656         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
657         return nullptr;
658     }
659     int32_t appIndex = 0;
660     if (!CommonFunAni::TryCastDoubleTo(aniAppIndex, &appIndex)) {
661         APP_LOGE("Cast aniAppIndex failed");
662         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, TYPE_NUMBER);
663         return nullptr;
664     }
665     int32_t bundleFlags = 0;
666     if (!CommonFunAni::TryCastDoubleTo(aniBundleFlags, &bundleFlags)) {
667         APP_LOGE("Cast aniBundleFlags failed");
668         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_FLAGS, TYPE_NUMBER);
669         return nullptr;
670     }
671     int32_t userId = EMPTY_USER_ID;
672     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
673         APP_LOGW("Parse userId failed, use default value");
674     }
675     if (userId == EMPTY_USER_ID) {
676         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
677     }
678 
679     auto iBundleMgr = CommonFunc::GetBundleMgr();
680     if (iBundleMgr == nullptr) {
681         APP_LOGE("Get bundle mgr failed");
682         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
683         return nullptr;
684     }
685     BundleInfo bundleInfo;
686     ErrCode ret = iBundleMgr->GetCloneBundleInfo(bundleName, bundleFlags, appIndex, bundleInfo, userId);
687     if (ret != ERR_OK) {
688         APP_LOGE("GetCloneBundleInfo failed ret: %{public}d", ret);
689         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
690             GET_APP_CLONE_BUNDLE_INFO, Constants::PERMISSION_GET_BUNDLE_INFO);
691         return nullptr;
692     }
693 
694     return CommonFunAni::ConvertBundleInfo(env, bundleInfo, bundleFlags);
695 }
696 
GetSpecifiedDistributionType(ani_env * env,ani_string aniBundleName)697 static ani_string GetSpecifiedDistributionType(ani_env* env, ani_string aniBundleName)
698 {
699     APP_LOGD("ani GetSpecifiedDistributionType called");
700     std::string bundleName;
701     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
702         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
703         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
704         return nullptr;
705     }
706     auto iBundleMgr = CommonFunc::GetBundleMgr();
707     if (iBundleMgr == nullptr) {
708         APP_LOGE("Get bundle mgr failed");
709         BusinessErrorAni::ThrowCommonError(env, ERROR_BUNDLE_SERVICE_EXCEPTION,
710             RESOURCE_NAME_OF_GET_SPECIFIED_DISTRIBUTION_TYPE, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
711         return nullptr;
712     }
713     std::string specifiedDistributionType;
714     ErrCode ret = iBundleMgr->GetSpecifiedDistributionType(bundleName, specifiedDistributionType);
715     if (ret != ERR_OK) {
716         APP_LOGE("GetSpecifiedDistributionType failed ret: %{public}d", ret);
717         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
718             RESOURCE_NAME_OF_GET_SPECIFIED_DISTRIBUTION_TYPE, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
719         return nullptr;
720     }
721     ani_string aniSpecifiedDistributionType = nullptr;
722     if (!CommonFunAni::StringToAniStr(env, specifiedDistributionType, aniSpecifiedDistributionType)) {
723         APP_LOGE("StringToAniStr failed");
724         return nullptr;
725     }
726     return aniSpecifiedDistributionType;
727 }
728 
GetBundleNameByUidNative(ani_env * env,ani_double aniUserId,ani_boolean aniIsSync)729 static ani_string GetBundleNameByUidNative(ani_env* env, ani_double aniUserId, ani_boolean aniIsSync)
730 {
731     APP_LOGD("ani GetBundleNameByUid called");
732     int32_t userId = 0;
733     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
734         APP_LOGE("Cast userId failed");
735         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, Constants::UID, TYPE_NUMBER);
736         return nullptr;
737     }
738 
739     std::string bundleName;
740     ani_string aniBundleName = nullptr;
741     bool queryOwn = (userId == IPCSkeleton::GetCallingUid());
742     if (queryOwn) {
743         std::lock_guard<std::mutex> lock(g_aniOwnBundleNameMutex);
744         if (!g_aniOwnBundleName.empty()) {
745             APP_LOGD("query own bundleName, has cache, no need to query from host");
746             int32_t appIndex = 0;
747             CommonFunc::GetBundleNameAndIndexByName(g_aniOwnBundleName, bundleName, appIndex);
748             if (CommonFunAni::StringToAniStr(env, bundleName, aniBundleName)) {
749                 return aniBundleName;
750             } else {
751                 APP_LOGE("Convert ani_string failed");
752                 return nullptr;
753             }
754         }
755     }
756     int32_t appIndex = 0;
757     ErrCode ret = BundleManagerHelper::InnerGetAppCloneIdentity(userId, bundleName, appIndex);
758     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
759     if (ret != ERR_OK) {
760         BusinessErrorAni::ThrowCommonError(
761             env, ret, isSync ? GET_BUNDLE_NAME_BY_UID_SYNC : GET_BUNDLE_NAME_BY_UID, BUNDLE_PERMISSIONS);
762         return nullptr;
763     }
764     std::lock_guard<std::mutex> lock(g_aniOwnBundleNameMutex);
765     if (queryOwn && g_aniOwnBundleName.empty()) {
766         g_aniOwnBundleName = bundleName;
767         if (appIndex > 0) {
768             g_aniOwnBundleName = std::to_string(appIndex) + "clone_" + bundleName;
769         }
770         APP_LOGD("put own bundleName = %{public}s to cache", g_aniOwnBundleName.c_str());
771     }
772 
773     if (CommonFunAni::StringToAniStr(env, bundleName, aniBundleName)) {
774         return aniBundleName;
775     } else {
776         APP_LOGE("Convert ani_string failed");
777         return nullptr;
778     }
779 }
780 
QueryAbilityInfoWithWantsNative(ani_env * env,ani_object aniWants,ani_double aniAbilityFlags,ani_double aniUserId)781 static ani_object QueryAbilityInfoWithWantsNative(ani_env* env,
782     ani_object aniWants, ani_double aniAbilityFlags, ani_double aniUserId)
783 {
784     APP_LOGD("ani QueryAbilityInfoWithWants called");
785     std::vector<OHOS::AAFwk::Want> wants;
786     int32_t abilityFlags = 0;
787     int32_t userId = EMPTY_USER_ID;
788     if (!ParseAniWantList(env, aniWants, wants) || wants.empty()) {
789         APP_LOGE("ParseAniWant failed");
790         BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, INVALID_WANT_ERROR);
791         return nullptr;
792     }
793     if (!CommonFunAni::TryCastDoubleTo(aniAbilityFlags, &abilityFlags)) {
794         APP_LOGE("Cast aniAbilityFlags failed");
795         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, ABILITY_FLAGS, TYPE_NUMBER);
796         return nullptr;
797     }
798     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
799         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
800     }
801 
802     if (userId == EMPTY_USER_ID) {
803         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
804     }
805     std::string bundleNames = "[";
806     for (uint32_t i = 0; i < wants.size(); i++) {
807         bundleNames += ((i > 0) ? "," : "");
808         bundleNames += wants[i].ToString();
809     }
810     bundleNames += "]";
811     const ANIQuery query(bundleNames, BATCH_QUERY_ABILITY_INFOS, abilityFlags, userId);
812     {
813         std::shared_lock<std::shared_mutex> lock(g_aniCacheMutex);
814         auto item = g_aniCache.find(query);
815         if (item != g_aniCache.end()) {
816             APP_LOGD("has cache, no need to query from host");
817             return reinterpret_cast<ani_object>(item->second);
818         }
819     }
820 
821     std::vector<AbilityInfo> abilityInfos;
822     ErrCode ret = BundleManagerHelper::InnerBatchQueryAbilityInfos(wants, abilityFlags, userId, abilityInfos);
823     if (ret != ERR_OK) {
824         APP_LOGE("BatchQueryAbilityInfos failed ret: %{public}d", ret);
825         BusinessErrorAni::ThrowCommonError(env, ret, BATCH_QUERY_ABILITY_INFOS, BUNDLE_PERMISSIONS);
826         return nullptr;
827     }
828     ani_object aniAbilityInfos =
829         CommonFunAni::ConvertAniArray(env, abilityInfos, CommonFunAni::ConvertAbilityInfo);
830     CheckBatchAbilityInfoCache(env, query, wants, abilityInfos, aniAbilityInfos);
831     return aniAbilityInfos;
832 }
833 
GetDynamicIconNative(ani_env * env,ani_string aniBundleName)834 static ani_string GetDynamicIconNative(ani_env* env, ani_string aniBundleName)
835 {
836     APP_LOGD("ani GetDynamicIcon called");
837     std::string bundleName;
838     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
839         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
840         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
841         return nullptr;
842     }
843     std::string moduleName;
844     ErrCode ret = BundleManagerHelper::InnerGetDynamicIcon(bundleName, moduleName);
845     if (ret != ERR_OK) {
846         APP_LOGE("GetDynamicIcon failed ret: %{public}d", ret);
847         BusinessErrorAni::ThrowCommonError(env, ret,
848             GET_DYNAMIC_ICON, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
849         return nullptr;
850     }
851     ani_string aniModuleName = nullptr;
852     if (!CommonFunAni::StringToAniStr(env, moduleName, aniModuleName)) {
853         APP_LOGE("StringToAniStr failed");
854         return nullptr;
855     }
856     return aniModuleName;
857 }
858 
IsAbilityEnabledNative(ani_env * env,ani_object aniAbilityInfo,ani_double aniAppIndex,ani_boolean aniIsSync)859 static ani_boolean IsAbilityEnabledNative(ani_env* env,
860     ani_object aniAbilityInfo, ani_double aniAppIndex, ani_boolean aniIsSync)
861 {
862     APP_LOGD("ani IsAbilityEnabled called");
863     bool isEnable = false;
864     AbilityInfo abilityInfo;
865     if (!CommonFunAni::ParseAbilityInfo(env, aniAbilityInfo, abilityInfo)) {
866         APP_LOGE("ParseAbilityInfo failed");
867         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, ABILITY_INFO, TYPE_OBJECT);
868         return isEnable;
869     }
870     int32_t appIndex = 0;
871     if (!CommonFunAni::TryCastDoubleTo(aniAppIndex, &appIndex)) {
872         APP_LOGE("Cast aniAppIndex failed");
873         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, TYPE_NUMBER);
874         return isEnable;
875     }
876     ErrCode ret = BundleManagerHelper::InnerIsAbilityEnabled(abilityInfo, isEnable, appIndex);
877     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
878     if (ret != ERR_OK) {
879         APP_LOGE("IsAbilityEnabled failed ret: %{public}d", ret);
880         BusinessErrorAni::ThrowCommonError(env, ret, isSync ? IS_ABILITY_ENABLED_SYNC : "", "");
881     }
882     return isEnable;
883 }
884 
SetAbilityEnabledNative(ani_env * env,ani_object aniAbilityInfo,ani_boolean aniIsEnable,ani_double aniAppIndex,ani_boolean aniIsSync)885 static void SetAbilityEnabledNative(ani_env* env,
886     ani_object aniAbilityInfo, ani_boolean aniIsEnable, ani_double aniAppIndex, ani_boolean aniIsSync)
887 {
888     APP_LOGD("ani SetAbilityEnabled called");
889     AbilityInfo abilityInfo;
890     bool isEnable = CommonFunAni::AniBooleanToBool(aniIsEnable);
891     if (!CommonFunAni::ParseAbilityInfo(env, aniAbilityInfo, abilityInfo)) {
892         APP_LOGE("ParseAbilityInfo failed");
893         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, ABILITY_INFO, TYPE_OBJECT);
894         return;
895     }
896     int32_t appIndex = 0;
897     if (!CommonFunAni::TryCastDoubleTo(aniAppIndex, &appIndex)) {
898         APP_LOGE("Cast aniAppIndex failed");
899         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, TYPE_NUMBER);
900         return;
901     }
902     ErrCode ret = BundleManagerHelper::InnerSetAbilityEnabled(abilityInfo, isEnable, appIndex);
903     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
904     if (ret != ERR_OK) {
905         APP_LOGE("SetAbilityEnabled failed ret: %{public}d", ret);
906         BusinessErrorAni::ThrowCommonError(
907             env, ret, isSync ? SET_ABILITY_ENABLED_SYNC : SET_ABILITY_ENABLED,
908             Constants::PERMISSION_CHANGE_ABILITY_ENABLED_STATE);
909     }
910 }
911 
SetApplicationEnabledNative(ani_env * env,ani_string aniBundleName,ani_boolean aniIsEnable,ani_double aniAppIndex,ani_boolean aniIsSync)912 static void SetApplicationEnabledNative(ani_env* env,
913     ani_string aniBundleName, ani_boolean aniIsEnable, ani_double aniAppIndex, ani_boolean aniIsSync)
914 {
915     APP_LOGD("ani SetApplicationEnabled called");
916     bool isEnable = CommonFunAni::AniBooleanToBool(aniIsEnable);
917     std::string bundleName;
918     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
919         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
920         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
921         return;
922     }
923     int32_t appIndex = 0;
924     if (!CommonFunAni::TryCastDoubleTo(aniAppIndex, &appIndex)) {
925         APP_LOGE("Cast aniAppIndex failed");
926         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, TYPE_NUMBER);
927         return;
928     }
929     ErrCode ret = BundleManagerHelper::InnerSetApplicationEnabled(bundleName, isEnable, appIndex);
930     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
931     if (ret != ERR_OK) {
932         APP_LOGE("SetApplicationEnabled failed ret: %{public}d", ret);
933         BusinessErrorAni::ThrowCommonError(
934             env, ret, isSync ? SET_APPLICATION_ENABLED_SYNC : SET_APPLICATION_ENABLED,
935             Constants::PERMISSION_CHANGE_ABILITY_ENABLED_STATE);
936     }
937 }
938 
QueryExtensionAbilityInfoNative(ani_env * env,ani_object aniWant,ani_enum_item aniExtensionAbilityType,ani_string aniExtensionAbilityTypeName,ani_double aniExtensionAbilityFlags,ani_double aniUserId,ani_boolean aniIsExtensionTypeName,ani_boolean aniIsSync)939 static ani_object QueryExtensionAbilityInfoNative(ani_env* env,
940     ani_object aniWant, ani_enum_item aniExtensionAbilityType, ani_string aniExtensionAbilityTypeName,
941     ani_double aniExtensionAbilityFlags, ani_double aniUserId,
942     ani_boolean aniIsExtensionTypeName, ani_boolean aniIsSync)
943 {
944     APP_LOGD("ani QueryExtensionAbilityInfo called");
945     OHOS::AAFwk::Want want;
946     ExtensionAbilityType extensionAbilityType = ExtensionAbilityType::UNSPECIFIED;
947     int32_t flags = 0;
948     int32_t userId = EMPTY_USER_ID;
949     std::string extensionTypeName;
950     bool isExtensionTypeName = CommonFunAni::AniBooleanToBool(aniIsExtensionTypeName);
951 
952     if (!ParseAniWant(env, aniWant, want)) {
953         APP_LOGE("ParseAniWant failed");
954         BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, INVALID_WANT_ERROR);
955         return nullptr;
956     }
957     if (isExtensionTypeName) {
958         if (!CommonFunAni::ParseString(env, aniExtensionAbilityTypeName, extensionTypeName)) {
959             APP_LOGE("parse extensionTypeName failed");
960             BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, EXTENSION_TYPE_NAME, TYPE_STRING);
961             return nullptr;
962         }
963     } else {
964         if (!EnumUtils::EnumETSToNative(env, aniExtensionAbilityType, extensionAbilityType)) {
965             APP_LOGE("Parse extensionAbilityType failed");
966             BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, EXTENSION_ABILITY_TYPE, TYPE_NUMBER);
967             return nullptr;
968         }
969     }
970     if (!CommonFunAni::TryCastDoubleTo(aniExtensionAbilityFlags, &flags)) {
971         APP_LOGE("Cast aniExtensionAbilityFlags failed");
972         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, FLAGS, TYPE_NUMBER);
973         return nullptr;
974     }
975     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
976         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
977     }
978     if (userId == EMPTY_USER_ID) {
979         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
980     }
981 
982     std::string key = want.ToString() + std::to_string(static_cast<int32_t>(extensionAbilityType));
983     const ANIQuery query(key, QUERY_EXTENSION_INFOS_SYNC, flags, userId);
984     {
985         std::shared_lock<std::shared_mutex> lock(g_aniCacheMutex);
986         auto item = g_aniCache.find(query);
987         if (item != g_aniCache.end()) {
988             APP_LOGD("ani extension has cache, no need to query from host");
989             return reinterpret_cast<ani_object>(item->second);
990         }
991     }
992 
993     auto iBundleMgr = CommonFunc::GetBundleMgr();
994     if (iBundleMgr == nullptr) {
995         APP_LOGE("GetBundleMgr failed");
996         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
997         return nullptr;
998     }
999     ErrCode ret = ERR_OK;
1000     std::vector<ExtensionAbilityInfo> extensionInfos;
1001     if (!isExtensionTypeName) {
1002         if (extensionAbilityType == ExtensionAbilityType::UNSPECIFIED) {
1003             APP_LOGD("Query aniExtensionAbilityInfo sync without type");
1004             ret = iBundleMgr->QueryExtensionAbilityInfosV9(want, flags, userId, extensionInfos);
1005         } else {
1006             APP_LOGD("Query aniExtensionAbilityInfo sync with type %{public}d",
1007                 static_cast<int32_t>(extensionAbilityType));
1008             ret = iBundleMgr->QueryExtensionAbilityInfosV9(want, extensionAbilityType, flags, userId, extensionInfos);
1009         }
1010     } else {
1011         APP_LOGD("Query aniExtensionAbilityInfo sync with extensionTypeName %{public}s", extensionTypeName.c_str());
1012         ret = iBundleMgr->QueryExtensionAbilityInfosWithTypeName(
1013             want, extensionTypeName, flags, userId, extensionInfos);
1014     }
1015 
1016     bool isSync = CommonFunAni::AniBooleanToBool(aniIsSync);
1017     if (ret != ERR_OK) {
1018         APP_LOGE("QueryExtensionAbilityInfo failed ret: %{public}d", ret);
1019         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
1020             isSync ? QUERY_EXTENSION_INFOS_SYNC : QUERY_EXTENSION_INFOS, BUNDLE_PERMISSIONS);
1021         return nullptr;
1022     }
1023     ani_object aniExtensionAbilityInfos =
1024         CommonFunAni::ConvertAniArray(env, extensionInfos, CommonFunAni::ConvertExtensionInfo);
1025     CheckInfoCache(env, query, want, extensionInfos, aniExtensionAbilityInfos);
1026     return aniExtensionAbilityInfos;
1027 }
1028 
QueryExAbilityInfoSyncWithoutWant(ani_env * env,ani_string aniExtensionAbilityTypeName,ani_double aniExtensionAbilityFlags,ani_double aniUserId)1029 static ani_object QueryExAbilityInfoSyncWithoutWant(ani_env* env, ani_string aniExtensionAbilityTypeName,
1030     ani_double aniExtensionAbilityFlags, ani_double aniUserId)
1031 {
1032     APP_LOGD("ani QueryExAbilityInfoSyncWithoutWant called");
1033     int32_t flags = 0;
1034     int32_t userId = EMPTY_USER_ID;
1035 
1036     std::string extensionTypeName;
1037     if (!CommonFunAni::ParseString(env, aniExtensionAbilityTypeName, extensionTypeName)) {
1038         APP_LOGE("parse extensionTypeName failed");
1039         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, EXTENSION_TYPE_NAME, TYPE_STRING);
1040         return nullptr;
1041     }
1042     if (extensionTypeName.empty()) {
1043         APP_LOGE("the input extensionAbilityType is empty");
1044         BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_EXTENSION_ABILITY_TYPE_EMPTY_ERROR);
1045         return nullptr;
1046     }
1047     if (!CommonFunAni::TryCastDoubleTo(aniExtensionAbilityFlags, &flags)) {
1048         APP_LOGE("Cast aniExtensionAbilityFlags failed");
1049         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, FLAGS, TYPE_NUMBER);
1050         return nullptr;
1051     }
1052     if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) {
1053         APP_LOGW("Parse userId failed, set this parameter to the caller userId");
1054     }
1055     if (userId == EMPTY_USER_ID) {
1056         userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
1057     }
1058 
1059     auto iBundleMgr = CommonFunc::GetBundleMgr();
1060     if (iBundleMgr == nullptr) {
1061         APP_LOGE("GetBundleMgr failed");
1062         BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION);
1063         return nullptr;
1064     }
1065     std::vector<ExtensionAbilityInfo> extensionInfos;
1066     ErrCode ret = iBundleMgr->QueryExtensionAbilityInfosOnlyWithTypeName(extensionTypeName,
1067         (flags < 0 ? 0 : static_cast<uint32_t>(flags)), userId, extensionInfos);
1068     if (ret != ERR_OK) {
1069         APP_LOGE("QueryExAbilityInfoSync without want failed ret: %{public}d", ret);
1070         BusinessErrorAni::ThrowCommonError(env, CommonFunc::ConvertErrCode(ret),
1071             QUERY_EXTENSION_INFOS_SYNC, BUNDLE_PERMISSIONS);
1072         return nullptr;
1073     }
1074     return CommonFunAni::ConvertAniArray(env, extensionInfos, CommonFunAni::ConvertExtensionInfo);
1075 }
1076 
EnableDynamicIconNative(ani_env * env,ani_string aniBundleName,ani_string aniModuleName)1077 static void EnableDynamicIconNative(ani_env* env, ani_string aniBundleName, ani_string aniModuleName)
1078 {
1079     APP_LOGD("ani EnableDynamicIcon called");
1080     std::string bundleName;
1081     if (!CommonFunAni::ParseString(env, aniBundleName, bundleName)) {
1082         APP_LOGE("bundleName %{public}s invalid", bundleName.c_str());
1083         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
1084         return;
1085     }
1086     std::string moduleName;
1087     if (!CommonFunAni::ParseString(env, aniModuleName, moduleName)) {
1088         APP_LOGE("moduleName %{public}s invalid", moduleName.c_str());
1089         BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
1090         return;
1091     }
1092 
1093     ErrCode ret = BundleManagerHelper::InnerEnableDynamicIcon(bundleName, moduleName, 0, 0, true);
1094     if (ret != ERR_OK) {
1095         APP_LOGE("EnableDynamicIcon failed ret: %{public}d", ret);
1096         BusinessErrorAni::ThrowCommonError(env, ret,
1097             ENABLE_DYNAMIC_ICON, Constants::PERMISSION_ACCESS_DYNAMIC_ICON);
1098     }
1099 }
1100 
1101 extern "C" {
ANI_Constructor(ani_vm * vm,uint32_t * result)1102 ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result)
1103 {
1104     APP_LOGI("ANI_Constructor called");
1105     ani_env* env;
1106     ani_status res = vm->GetEnv(ANI_VERSION_1, &env);
1107     RETURN_ANI_STATUS_IF_NOT_OK(res, "Unsupported ANI_VERSION_1");
1108 
1109     auto nsName = arkts::ani_signature::Builder::BuildNamespace({"@ohos", "bundle", "bundleManager", "bundleManager"});
1110     ani_namespace kitNs;
1111     res = env->FindNamespace(nsName.Descriptor().c_str(), &kitNs);
1112     RETURN_ANI_STATUS_IF_NOT_OK(res, "Not found nameSpace L@ohos/bundle/bundleManager/bundleManager;");
1113 
1114     std::array methods = {
1115         ani_native_function { "isApplicationEnabledNative", nullptr,
1116             reinterpret_cast<void*>(IsApplicationEnabledNative) },
1117         ani_native_function { "getBundleInfoForSelfNative", nullptr,
1118             reinterpret_cast<void*>(GetBundleInfoForSelfNative) },
1119         ani_native_function { "getBundleInfoNative", nullptr, reinterpret_cast<void*>(GetBundleInfoNative) },
1120         ani_native_function { "getApplicationInfoNative", nullptr, reinterpret_cast<void*>(GetApplicationInfoNative) },
1121         ani_native_function { "getAllBundleInfoNative", nullptr, reinterpret_cast<void*>(GetAllBundleInfoNative) },
1122         ani_native_function { "getAllApplicationInfoNative", nullptr,
1123             reinterpret_cast<void*>(GetAllApplicationInfoNative) },
1124         ani_native_function { "queryAbilityInfoSyncNative", nullptr,
1125             reinterpret_cast<void*>(QueryAbilityInfoSyncNative) },
1126         ani_native_function { "getAppCloneIdentityNative", nullptr,
1127             reinterpret_cast<void*>(GetAppCloneIdentityNative) },
1128         ani_native_function { "getAbilityLabelNative", nullptr, reinterpret_cast<void*>(GetAbilityLabelNative) },
1129         ani_native_function { "getLaunchWantForBundleNative", nullptr,
1130             reinterpret_cast<void*>(GetLaunchWantForBundleNative) },
1131         ani_native_function { "getAppCloneBundleInfoNative", nullptr,
1132             reinterpret_cast<void*>(GetAppCloneBundleInfoNative) },
1133         ani_native_function { "getSpecifiedDistributionType", nullptr,
1134             reinterpret_cast<void*>(GetSpecifiedDistributionType) },
1135         ani_native_function { "getBundleNameByUidNative", nullptr, reinterpret_cast<void*>(GetBundleNameByUidNative) },
1136         ani_native_function { "queryExtensionAbilityInfoNative", nullptr,
1137             reinterpret_cast<void*>(QueryExtensionAbilityInfoNative) },
1138         ani_native_function { "queryExAbilityInfoSyncWithoutWantNative", nullptr,
1139             reinterpret_cast<void*>(QueryExAbilityInfoSyncWithoutWant) },
1140         ani_native_function { "isAbilityEnabledNative", nullptr,
1141             reinterpret_cast<void*>(IsAbilityEnabledNative) },
1142         ani_native_function { "setAbilityEnabledNative", nullptr,
1143             reinterpret_cast<void*>(SetAbilityEnabledNative) },
1144         ani_native_function { "setApplicationEnabledNative", nullptr,
1145             reinterpret_cast<void*>(SetApplicationEnabledNative) },
1146         ani_native_function { "getDynamicIconNative", nullptr, reinterpret_cast<void*>(GetDynamicIconNative) },
1147         ani_native_function { "queryAbilityInfoWithWantsNative", nullptr,
1148             reinterpret_cast<void*>(QueryAbilityInfoWithWantsNative) },
1149         ani_native_function { "enableDynamicIconNative", nullptr, reinterpret_cast<void*>(EnableDynamicIconNative) },
1150     };
1151 
1152     res = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size());
1153     RETURN_ANI_STATUS_IF_NOT_OK(res, "Cannot bind native methods");
1154 
1155     *result = ANI_VERSION_1;
1156 
1157     RegisterANIClearCacheListenerAndEnv(vm);
1158 
1159     APP_LOGI("ANI_Constructor finished");
1160 
1161     return ANI_OK;
1162 }
1163 }
1164 
DoClearCache()1165 void ANIClearCacheListener::DoClearCache()
1166 {
1167     std::unique_lock<std::shared_mutex> lock(g_aniCacheMutex);
1168     ani_env* env = nullptr;
1169     ani_option interopEnabled { "--interop=disable", nullptr };
1170     ani_options aniArgs { 1, &interopEnabled };
1171     if (g_vm == nullptr) {
1172         APP_LOGE("g_vm is empty");
1173         return;
1174     }
1175     ani_status status = g_vm->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env);
1176     if (status != ANI_OK) {
1177         APP_LOGE("AttachCurrentThread fail %{public}d", status);
1178         return;
1179     }
1180     if (env == nullptr) {
1181         APP_LOGE("env is empty");
1182     } else {
1183         for (auto& item : g_aniCache) {
1184             env->GlobalReference_Delete(item.second);
1185         }
1186     }
1187     g_vm->DetachCurrentThread();
1188     g_aniCache.clear();
1189 }
1190 
HandleCleanEnv(void * data)1191 void ANIClearCacheListener::HandleCleanEnv(void* data)
1192 {
1193     DoClearCache();
1194 }
1195 
ANIClearCacheListener(const EventFwk::CommonEventSubscribeInfo & subscribeInfo)1196 ANIClearCacheListener::ANIClearCacheListener(const EventFwk::CommonEventSubscribeInfo& subscribeInfo)
1197     : EventFwk::CommonEventSubscriber(subscribeInfo)
1198 {}
1199 
OnReceiveEvent(const EventFwk::CommonEventData & data)1200 void ANIClearCacheListener::OnReceiveEvent(const EventFwk::CommonEventData& data)
1201 {
1202     DoClearCache();
1203 }
1204 
RegisterANIClearCacheListenerAndEnv(ani_vm * vm)1205 void RegisterANIClearCacheListenerAndEnv(ani_vm* vm)
1206 {
1207     std::lock_guard<std::mutex> lock(g_aniClearCacheListenerMutex);
1208     if (g_aniClearCacheListener != nullptr) {
1209         return;
1210     }
1211     EventFwk::MatchingSkills matchingSkills;
1212     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
1213     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
1214     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
1215     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
1216     g_aniClearCacheListener = std::make_shared<ANIClearCacheListener>(subscribeInfo);
1217     (void)EventFwk::CommonEventManager::SubscribeCommonEvent(g_aniClearCacheListener);
1218     g_vm = vm;
1219 }
1220 } // namespace AppExecFwk
1221 } // namespace OHOS
1222