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