diff --git a/interfaces/inner_api/appexecfwk_base/include/bundle_info.h b/interfaces/inner_api/appexecfwk_base/include/bundle_info.h index c7a5d1e16ccb44725ff21f091f13533a9d9a2611..ab3bdd0582a274765bdbe6761de436332bda6dd8 100644 --- a/interfaces/inner_api/appexecfwk_base/include/bundle_info.h +++ b/interfaces/inner_api/appexecfwk_base/include/bundle_info.h @@ -66,6 +66,7 @@ enum class GetBundleInfoFlag { GET_BUNDLE_INFO_OF_ANY_USER = 0x00002000, GET_BUNDLE_INFO_EXCLUDE_CLONE = 0x00004000, GET_BUNDLE_INFO_WITH_CLOUD_KIT = 0x00008000, + GET_BUNDLE_INFO_WITH_BROKER = 0x00010000, }; struct RequestPermissionUsedScene : public Parcelable { diff --git a/interfaces/inner_api/appexecfwk_core/include/bundle_framework_core_ipc_interface_code.h b/interfaces/inner_api/appexecfwk_core/include/bundle_framework_core_ipc_interface_code.h index fa43eea1e577a3d58fc54e4fdd95545d14f62aaa..1128448bb340d812b1d5f30e5b5323b826529aab 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundle_framework_core_ipc_interface_code.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundle_framework_core_ipc_interface_code.h @@ -221,6 +221,7 @@ enum class BundleMgrInterfaceCode : uint32_t { BATCH_GET_ADDITIONAL_INFO = 195, BATCH_GET_BUNDLE_STATS = 196, GET_SHORTCUT_INFO_BY_APPINDEX = 197, + GET_ALL_BUNDLE_NAMES = 198, }; /* SAID: 401-85 Interface No.85 subservice also provides the following interfaces */ diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h index 1d940bb76ef7f88cb7872931cabf2f6223c95629..aad1fd00a0ae5f5aa93d44ce42ae95397157b4f4 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h @@ -915,6 +915,13 @@ private: ErrCode HandleGreatOrEqualTargetAPIVersion(MessageParcel &data, MessageParcel &reply); ErrCode HandleSetShortcutVisibleForSelf(MessageParcel &data, MessageParcel &reply); ErrCode HandleGetAllShortcutInfoForSelf(MessageParcel &data, MessageParcel &reply); + /** + * @brief Handles the GetAllBundleNames function called from a IBundleMgr proxy object. + * @param data Indicates the data to be read. + * @param reply Indicates the reply to be sent; + * @return Returns ERR_OK if called successfully; returns error code otherwise. + */ + ErrCode HandleGetAllBundleNames(MessageParcel &data, MessageParcel &reply); private: /** * @brief Write a parcelabe vector objects to the proxy node. diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h index ece541e8d2b0876edd883eb7c3dc792624b15043..f9e142d282cf01a1763a2782c335b85198fa3eb9 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h @@ -1245,6 +1245,15 @@ public: virtual bool GreatOrEqualTargetAPIVersion(const int32_t platformVersion, const int32_t minorVersion, const int32_t patchVersion) override; + + /** + * @brief Obtains all bundle names of a specified user. + * @param bundleNames Indicates the vector of the bundle names. + * @param flags Indicates the flags to control the bundle list. + * @param userId Indicates the user ID. + * @return Returns ERR_OK if the operation is successful; returns other error codes otherwise. + */ + virtual ErrCode GetAllBundleNames(std::vector &bundleNames, uint32_t flags, int32_t userId) override; private: /** * @brief Send a command message from the proxy object. diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp index 682a25889b1c0dab568e7c7501d3f7d59b1fac0b..2473e9940a7659483cd2867667bc6732cee2f43d 100644 --- a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp @@ -701,6 +701,9 @@ int BundleMgrHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa case static_cast(BundleMgrInterfaceCode::GREAT_OR_EQUAL_API_TARGET_VERSION): errCode = HandleGreatOrEqualTargetAPIVersion(data, reply); break; + case static_cast(BundleMgrInterfaceCode::GET_ALL_BUNDLE_NAMES): + errCode = HandleGetAllBundleNames(data, reply); + break; default : APP_LOGW("bundleMgr host receives unknown code %{public}u", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -4875,5 +4878,24 @@ ErrCode BundleMgrHost::HandleGreatOrEqualTargetAPIVersion(MessageParcel &data, M } return ERR_OK; } + +ErrCode BundleMgrHost::HandleGetAllBundleNames(MessageParcel &data, MessageParcel &reply) +{ + HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr); + uint32_t flags = data.ReadUint32(); + int32_t userId = data.ReadInt32(); + std::vector bundleNames; + ErrCode ret = GetAllBundleNames(bundleNames, flags, userId); + if (!reply.WriteInt32(ret)) { + APP_LOGE("GetAllBundleNames write failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + reply.SetDataCapacity(MAX_CAPACITY_BUNDLES); + if (ret == ERR_OK && !reply.WriteStringVector(bundleNames)) { + APP_LOGE("Write all bundleNames results failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + return ERR_OK; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp index 5f4937e3eb9f56a2a73818a8db9070a7ba6bb13b..6db5e19438303272732f983a8f83d5e20546bc80 100644 --- a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp @@ -6374,5 +6374,40 @@ bool BundleMgrProxy::GreatOrEqualTargetAPIVersion(const int32_t platformVersion, } return reply.ReadBool(); } + +ErrCode BundleMgrProxy::GetAllBundleNames(std::vector &bundleNames, uint32_t flags, int32_t userId) +{ + APP_LOGD("GetAllBundleNames: userId: %{public}d", userId); + HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr); + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + APP_LOGE("Fail to GetAllBundleNames due to write InterfaceToken fail"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + if (!data.WriteUint32(flags)) { + APP_LOGE("Fail to GetAllBundleNames due to write flags fail"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + if (!data.WriteInt32(userId)) { + APP_LOGE("Fail to GetAllBundleNames due to write userId fail"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + MessageParcel reply; + if (!SendTransactCmd(BundleMgrInterfaceCode::GET_ALL_BUNDLE_NAMES, data, reply)) { + APP_LOGE("Fail to GetAllBundleNames from server"); + return ERR_BUNDLE_MANAGER_IPC_TRANSACTION; + } + ErrCode ret = reply.ReadInt32(); + if (ret != ERR_OK) { + APP_LOGE("Reply err : %{public}d", ret); + return ret; + } + if (!reply.ReadStringVector(&bundleNames)) { + APP_LOGE("Fail to GetAllBundleNames from reply"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + APP_LOGD("GetAllBundleNames: ret: %{public}d, count: %{public}zu", ret, bundleNames.size()); + return ERR_OK; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/include/bundle_data_mgr.h b/services/bundlemgr/include/bundle_data_mgr.h index f06c2d5c74a732930ab3af2810fc1fa5a3b8f545..75324cb495b8fe032d70521c6aba43890b762eb3 100644 --- a/services/bundlemgr/include/bundle_data_mgr.h +++ b/services/bundlemgr/include/bundle_data_mgr.h @@ -1167,6 +1167,14 @@ public: void FilterShortcutJson(nlohmann::json &jsonResult); ErrCode IsSystemApp(const std::string &bundleName, bool &isSystemApp); void UpdateDesktopShortcutInfo(const std::string &bundleName); + /** + * @brief Obtains all bundle names of a specified user. + * @param bundleNames Indicates the vector of the bundle names. + * @param flags Indicates the flags to control the bundle list. + * @param userId Indicates the user ID. + * @return Returns ERR_OK if successfully obtained; returns error code otherwise. + */ + ErrCode GetAllBundleNames(std::vector &bundleNames, uint32_t flags, int32_t userId); private: /** diff --git a/services/bundlemgr/include/bundle_mgr_host_impl.h b/services/bundlemgr/include/bundle_mgr_host_impl.h index 8e98379d06f9555dded9fa0659015f4d236e2f7d..17124d975e17a6452280b9c3f4d8238eec295c13 100644 --- a/services/bundlemgr/include/bundle_mgr_host_impl.h +++ b/services/bundlemgr/include/bundle_mgr_host_impl.h @@ -1136,6 +1136,14 @@ public: virtual ErrCode RegisterPluginEventCallback(const sptr &pluginEventCallback) override; virtual ErrCode UnregisterPluginEventCallback(const sptr &pluginEventCallback) override; virtual ErrCode GetAllShortcutInfoForSelf(std::vector &shortcutInfos) override; + /** + * @brief Obtains all bundle names of a specified user. + * @param Indicates the vector of the bundle names. + * @param flags Indicates the flags to control the bundle list. + * @param userId Indicates the user ID. + * @return Returns ERR_OK if successfully obtained; returns error code otherwise. + */ + virtual ErrCode GetAllBundleNames(std::vector &bundleNames, uint32_t flags, int32_t userId) override; private: bool GetLabelByBundleName(const std::string &bundleName, int32_t userId, std::string &label); diff --git a/services/bundlemgr/src/bundle_data_mgr.cpp b/services/bundlemgr/src/bundle_data_mgr.cpp index aa973b472e4f22a9e651c1c3e537af70a6743ad3..1912262738a8c3aec85740d096447394464ddfa9 100644 --- a/services/bundlemgr/src/bundle_data_mgr.cpp +++ b/services/bundlemgr/src/bundle_data_mgr.cpp @@ -11184,5 +11184,53 @@ void BundleDataMgr::UpdateDesktopShortcutInfo(const std::string &bundleName) } shortcutStorage_->UpdateDesktopShortcutInfo(bundleName, shortcutInfos); } + +ErrCode BundleDataMgr::GetAllBundleNames(std::vector &bundleNames, uint32_t flags, int32_t userId) +{ + int32_t requestUserId = GetUserId(userId); + if (requestUserId == Constants::INVALID_USERID) { + APP_LOGE("Input invalid userid, userId:%{public}d", userId); + return ERR_BUNDLE_MANAGER_INVALID_USER_ID; + } + + std::shared_lock lock(bundleInfoMutex_); + for (const auto &[bundleName, innerInfo] : bundleInfos_) { + if (innerInfo.GetResponseUserId(requestUserId) == Constants::INVALID_USERID) { + continue; + } + if (!(flags & static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE))) { + if (innerInfo.IsDisabled() || !innerInfo.GetApplicationEnabled(requestUserId)) { + continue; + } + } + bundleNames.emplace_back(bundleName); + } + lock.unlock(); + + if ((flags & + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_BROKER)) == + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_BROKER)) { + if (DelayedSingleton::GetInstance()->IsBrokerServiceStarted()) { + APP_LOGD("Querying bundle infos from broker service to get bundle names."); + std::vector brokerBundleInfos; + auto bmsExtensionClient = std::make_shared(); + ErrCode ret = bmsExtensionClient->GetBundleInfos(flags, brokerBundleInfos, userId); + if (ret == ERR_OK) { + for (const auto& bundleInfo : brokerBundleInfos) { + if (!bundleInfo.name.empty()) { + bundleNames.emplace_back(bundleInfo.name); + } + } + } else { + APP_LOGW("Failed to get bundle infos from broker, errcode: %{public}d", ret); + } + } + } + std::sort(bundleNames.begin(), bundleNames.end()); + bundleNames.erase(std::unique(bundleNames.begin(), bundleNames.end()), bundleNames.end()); + APP_LOGD("Found %{public}zu total unique bundle(s) for user %{public}d with flags=%{public}u", + bundleNames.size(), userId, flags); + return ERR_OK; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/bundle_mgr_host_impl.cpp b/services/bundlemgr/src/bundle_mgr_host_impl.cpp index b97019e379ccc88a35a547d4905450701a5de5dc..41379d42692ca2780298dfa5c3d201558117bf9d 100644 --- a/services/bundlemgr/src/bundle_mgr_host_impl.cpp +++ b/services/bundlemgr/src/bundle_mgr_host_impl.cpp @@ -5779,5 +5779,21 @@ bool BundleMgrHostImpl::GreatOrEqualTargetAPIVersion(const int32_t platformVersi } return dataMgr->GreatOrEqualTargetAPIVersion(platformVersion, minorVersion, patchVersion); } + +ErrCode BundleMgrHostImpl::GetAllBundleNames(std::vector &bundleNames, uint32_t flags, int32_t userId) +{ + APP_LOGD("start to get all bundle names for user %{public}d", userId); + if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_GET_INSTALLED_BUNDLE_LIST)) { + APP_LOGE("verify calling permission failed"); + return ERR_BUNDLE_MANAGER_PERMISSION_DENIED; + } + + auto dataMgr = GetDataMgrFromService(); + if (dataMgr == nullptr) { + APP_LOGE("DataMgr is nullptr"); + return ERR_BUNDLE_MANAGER_INTERNAL_ERROR; + } + return dataMgr->GetAllBundleNames(bundleNames, flags, userId); +} } // namespace AppExecFwk } // namespace OHOS