diff --git a/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h b/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h index b30ef526b9ce2193345189ba228c6af4a2dab1be..967d6c7100f7aec2cead40ca2df5112524c423a1 100644 --- a/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h +++ b/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h @@ -27,6 +27,8 @@ namespace OHOS { namespace AppExecFwk { namespace Constants { constexpr const char* TYPE_ONLY_MATCH_WILDCARD = "reserved/wildcard"; +constexpr const char* TYPE_WILDCARD = "*/*"; +constexpr const char* GENERAL_OBJECT = "general.object"; constexpr const char* EMPTY_STRING = ""; constexpr const char* FILE_UNDERLINE = "_"; constexpr const char* BUNDLE_CODE_DIR = "/data/app/el1/bundle/public"; @@ -98,6 +100,7 @@ constexpr const char* PERMISSION_UNINSTALL_PLUGIN = "ohos.permission.UNINSTALL_P constexpr const char* PERMISSION_PERFORM_LOCAL_DEBUG = "ohos.permission.PERFORM_LOCAL_DEBUG"; constexpr const char* PERMISSION_GET_ABILITY_INFO = "ohos.permission.GET_ABILITY_INFO"; constexpr const char* PERMISSION_BMS_INTERACT_ACROSS_LOCAL_ACCOUNTS = "ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS"; +constexpr const char* PERMISSION_MANAGE_SELF_SKILLS = "ohos.permission.MANAGE_SELF_SKILLS"; enum class AppType { SYSTEM_APP = 0, diff --git a/interfaces/inner_api/appexecfwk_base/src/application_info.cpp b/interfaces/inner_api/appexecfwk_base/src/application_info.cpp index f0c0cd43206f7c3a131970f1a2382d1e3c67a39e..415a0ecbad64dcc247e0b73a3130f9e082fbf9a0 100644 --- a/interfaces/inner_api/appexecfwk_base/src/application_info.cpp +++ b/interfaces/inner_api/appexecfwk_base/src/application_info.cpp @@ -593,7 +593,7 @@ bool ApplicationInfo::ReadFromParcel(Parcel &parcel) std::unique_ptr multiAppModePtr(parcel.ReadParcelable()); if (!multiAppModePtr) { - APP_LOGE("icon ReadParcelable failed"); + APP_LOGE("icon ReadParcelable failed"); return false; } multiAppMode = *multiAppModePtr; diff --git a/interfaces/inner_api/appexecfwk_base/src/skill.cpp b/interfaces/inner_api/appexecfwk_base/src/skill.cpp index c170fe80f9e719843d2db6f542cec708c56329c3..6c5277bba5d024961c815e130e8ce052fa605b74 100644 --- a/interfaces/inner_api/appexecfwk_base/src/skill.cpp +++ b/interfaces/inner_api/appexecfwk_base/src/skill.cpp @@ -50,11 +50,9 @@ constexpr const char* PARAM_SEPARATOR = "?"; constexpr const char* PORT_SEPARATOR = ":"; constexpr const char* SCHEME_SEPARATOR = "://"; constexpr const char* PATH_SEPARATOR = "/"; -constexpr const char* TYPE_WILDCARD = "*/*"; const char WILDCARD = '*'; constexpr const char* TYPE_ONLY_MATCH_WILDCARD = "reserved/wildcard"; const char* LINK_FEATURE = "linkFeature"; -const char* GENERAL_OBJECT = "general.object"; const uint32_t PROTOCOL_OFFSET = 3; }; // namespace @@ -468,7 +466,7 @@ bool Skill::MatchType(const std::string &type, const std::string &skillUriType) // only match */* or general.object if (type == TYPE_ONLY_MATCH_WILDCARD) { - return skillUriType == TYPE_WILDCARD || skillUriType == GENERAL_OBJECT; + return skillUriType == Constants::TYPE_WILDCARD || skillUriType == Constants::GENERAL_OBJECT; } bool containsUtd = false; @@ -477,7 +475,7 @@ bool Skill::MatchType(const std::string &type, const std::string &skillUriType) return matchUtdRet; } - if (type == TYPE_WILDCARD || skillUriType == TYPE_WILDCARD) { + if (type == Constants::TYPE_WILDCARD || skillUriType == Constants::TYPE_WILDCARD) { // param is */* or config is */* return true; } diff --git a/interfaces/inner_api/appexecfwk_core/BUILD.gn b/interfaces/inner_api/appexecfwk_core/BUILD.gn index a1b68f4a20c2bb3ebb0b256ef6d9f054d66b8822..43ab2dfcb6189953b69a6bd825e7e975a4890463 100644 --- a/interfaces/inner_api/appexecfwk_core/BUILD.gn +++ b/interfaces/inner_api/appexecfwk_core/BUILD.gn @@ -112,6 +112,7 @@ ohos_shared_library("appexecfwk_core") { "src/bundlemgr/clean_cache_callback_host.cpp", "src/bundlemgr/clean_cache_callback_proxy.cpp", "src/bundlemgr/launcher_service.cpp", + "src/bundlemgr/param_validator.cpp", "src/bundlemgr/process_cache_callback_host.cpp", "src/bundlemgr/process_cache_callback_proxy.cpp", "src/bundlemgr/status_receiver_host.cpp", 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 be59b80bd80fd7deb315363bbc87c8bade0ed27f..dbf623dc93b120007c4d4f0b755c555956c08e29 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 @@ -228,6 +228,7 @@ enum class BundleMgrInterfaceCode : uint32_t { IS_DEBUGGABLE_APPLICATION = 202, GET_ALL_BUNDLE_NAMES = 203, GET_ABILITY_RESOURCE_INFO = 204, + SET_ABILITY_FILE_TYPES_FOR_SELF = 205, }; /* 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 0b96b59aa8aa012f42ae474e8b14192ad26e79b8..b0e2025d6d9484b9273bdcbba4ec8eba4f333765 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 @@ -577,6 +577,7 @@ private: * @return Returns ERR_OK if called successfully; returns error code otherwise. */ ErrCode HandleSetCloneAbilityEnabled(MessageParcel &data, MessageParcel &reply); + ErrCode HandleSetAbilityFileTypesForSelf(MessageParcel &data, MessageParcel &reply); /** * @brief Handles the GetAllFormsInfo function called from a IBundleMgr proxy object. * @param data Indicates the data to be read. diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h index b2968a5969cc3623f0dd9da1155267db4123f0ef..9d4130b1783ae5648ec8ed25a7ce2ab3ac156fa3 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h @@ -1890,6 +1890,11 @@ public: { return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR; } + virtual ErrCode SetAbilityFileTypesForSelf(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes) + { + return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR; + } }; #define WRITE_PARCEL(func) \ 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 06878c3b918bcbf5468e803479261cada6b1c22a..846b6aa7dd9f773ac02391c0baa51b8dbfdbd760 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 @@ -727,6 +727,8 @@ public: */ virtual ErrCode SetCloneAbilityEnabled(const AbilityInfo &abilityInfo, int32_t appIndex, bool isEnabled, int32_t userId = Constants::UNSPECIFIED_USERID) override; + virtual ErrCode SetAbilityFileTypesForSelf(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes) override; /** * @brief Obtains the interface used to install and uninstall bundles through the proxy object. * @return Returns a pointer to IBundleInstaller class if exist; returns nullptr otherwise. diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/param_validator.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/param_validator.h new file mode 100644 index 0000000000000000000000000000000000000000..ba972ff071066912b83d372fc9f057bd6281ada1 --- /dev/null +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/param_validator.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_BUNDLEMGR_PARAM_VALIDATOR_H +#define FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_BUNDLEMGR_PARAM_VALIDATOR_H + +#include +#include + +namespace OHOS { +namespace AppExecFwk { +class ParamValidator final { +public: + static bool ValidateAbilityFileTypes(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_INTERFACES_INNERKITS_APPEXECFWK_CORE_INCLUDE_BUNDLEMGR_PARAM_VALIDATOR_H 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 bcbfc8bb7a11fa3519529be825afa06c78a69e4b..abe90a6b35ddc0577fa718e1fce4182764d2fdb6 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 @@ -708,6 +708,9 @@ int BundleMgrHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa case static_cast(BundleMgrInterfaceCode::GET_ABILITY_RESOURCE_INFO): errCode = HandleGetAbilityResourceInfo(data, reply); break; + case static_cast(BundleMgrInterfaceCode::SET_ABILITY_FILE_TYPES_FOR_SELF): + errCode = HandleSetAbilityFileTypesForSelf(data, reply); + break; default : APP_LOGW("bundleMgr host receives unknown code %{public}u", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -2231,6 +2234,24 @@ ErrCode BundleMgrHost::HandleSetCloneAbilityEnabled(MessageParcel &data, Message return ERR_OK; } +ErrCode BundleMgrHost::HandleSetAbilityFileTypesForSelf(MessageParcel &data, MessageParcel &reply) +{ + HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr); + std::string moduleName = data.ReadString(); + std::string abilityName = data.ReadString(); + std::vector fileTypes; + if (!data.ReadStringVector(&fileTypes)) { + APP_LOGE("ReadStringVector failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + ErrCode ret = SetAbilityFileTypesForSelf(moduleName, abilityName, fileTypes); + if (!reply.WriteInt32(ret)) { + APP_LOGE("WriteInt32 failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + return ERR_OK; +} + ErrCode BundleMgrHost::HandleGetAbilityInfo(MessageParcel &data, MessageParcel &reply) { HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr); 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 f973df156964dd0d4ef2b69a78d8b135ecbb5c75..bb3d6f8a475322f7bc3321d0b926f15a08ce9cf3 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 @@ -41,6 +41,7 @@ #include "ffrt.h" #include "hitrace_meter.h" #include "json_util.h" +#include "param_validator.h" #ifdef BUNDLE_FRAMEWORK_QUICK_FIX #include "quick_fix_manager_proxy.h" #endif @@ -2560,6 +2561,42 @@ ErrCode BundleMgrProxy::SetCloneAbilityEnabled( return reply.ReadInt32(); } +ErrCode BundleMgrProxy::SetAbilityFileTypesForSelf(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes) +{ + HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr); + LOG_NOFUNC_I(BMS_TAG_QUERY, "SetAbilityFileTypesForSelf -m:%{public}s, -a:%{public}s", + moduleName.c_str(), abilityName.c_str()); + if (!ParamValidator::ValidateAbilityFileTypes(moduleName, abilityName, fileTypes)) { + LOG_NOFUNC_E(BMS_TAG_QUERY, "SetAbilityFileTypesForSelf invalid params"); + return ERR_BUNDLE_MANAGER_PARAM_ERROR; + } + MessageParcel data; + (void)data.SetMaxCapacity(Constants::CAPACITY_SIZE); + if (!data.WriteInterfaceToken(GetDescriptor())) { + LOG_NOFUNC_E(BMS_TAG_QUERY, "SetAbilityFileTypesForSelf write InterfaceToken failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + if (!data.WriteString(moduleName)) { + LOG_NOFUNC_E(BMS_TAG_QUERY, "SetAbilityFileTypesForSelf write moduleName failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + if (!data.WriteString(abilityName)) { + LOG_NOFUNC_E(BMS_TAG_QUERY, "SetAbilityFileTypesForSelf write abilityName failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + if (!data.WriteStringVector(fileTypes)) { + LOG_NOFUNC_E(BMS_TAG_QUERY, "SetAbilityFileTypesForSelf write fileTypes failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + MessageParcel reply; + if (!SendTransactCmd(BundleMgrInterfaceCode::SET_ABILITY_FILE_TYPES_FOR_SELF, data, reply)) { + APP_LOGE("SetAbilityFileTypesForSelf SendTransactCmd failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + return reply.ReadInt32(); +} + bool BundleMgrProxy::GetAbilityInfo( const std::string &bundleName, const std::string &abilityName, AbilityInfo &abilityInfo) { diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/param_validator.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/param_validator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f4eedc285e9fa097a269887dfa01b421a5c7c88 --- /dev/null +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/param_validator.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "param_validator.h" + +#include "app_log_wrapper.h" +#include "bundle_constants.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr uint16_t MAX_FILE_TYPE_VECTOR_SIZE = 1024; +constexpr uint16_t MAX_FILE_TYPE_SIZE = 512; +} + +bool ParamValidator::ValidateAbilityFileTypes(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes) +{ + if (moduleName.empty()) { + APP_LOGE_NOFUNC("moduleName empty"); + return false; + } + if (abilityName.empty()) { + APP_LOGE_NOFUNC("abilityName empty"); + return false; + } + if (fileTypes.empty()) { + APP_LOGE_NOFUNC("fileTypes empty"); + return false; + } + if (fileTypes.size() > MAX_FILE_TYPE_VECTOR_SIZE) { + APP_LOGE_NOFUNC("fileTypes size exceed max limit"); + return false; + } + for (const std::string &fileType : fileTypes) { + if (fileType.empty()) { + APP_LOGE_NOFUNC("fileType empty"); + return false; + } + if (fileType.size() > MAX_FILE_TYPE_SIZE) { + APP_LOGE_NOFUNC("fileType size exceed max limit"); + return false; + } + if (fileType == Constants::TYPE_WILDCARD || fileType == Constants::GENERAL_OBJECT) { + APP_LOGE_NOFUNC("not allowed fileType:%{public}s", fileType.c_str()); + return false; + } + } + return true; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/interfaces/kits/ani/bundle_manager/ani_bundle_manager.cpp b/interfaces/kits/ani/bundle_manager/ani_bundle_manager.cpp index 3a7976008747973b56e72087b4377fc923fc1190..16b4ab43c95ef01bbe176e0dec0cbcd0fe17d57b 100644 --- a/interfaces/kits/ani/bundle_manager/ani_bundle_manager.cpp +++ b/interfaces/kits/ani/bundle_manager/ani_bundle_manager.cpp @@ -936,6 +936,36 @@ static void SetApplicationEnabledNative(ani_env* env, } } +static void SetAbilityFileTypesForSelfNative(ani_env* env, + ani_string aniModuleName, ani_string aniAbilityName, ani_object aniFileTypes) +{ + APP_LOGD("ANI SetAbilityFileTypesForSelf begin"); + std::string moduleName; + if (!CommonFunAni::ParseString(env, aniModuleName, moduleName)) { + APP_LOGE("parse moduleName failed"); + BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING); + return; + } + std::string abilityName; + if (!CommonFunAni::ParseString(env, aniAbilityName, abilityName)) { + APP_LOGE("parse abilityName failed"); + BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, ABILITY_NAME, TYPE_STRING); + return; + } + std::vector fileTypes; + if (!CommonFunAni::ParseStrArray(env, aniFileTypes, fileTypes)) { + APP_LOGE("parse fileTypes failed"); + BusinessErrorAni::ThrowCommonError(env, ERROR_PARAM_CHECK_ERROR, FILE_TYPES, TYPE_ARRAY); + return; + } + ErrCode ret = BundleManagerHelper::InnerSetAbilityFileTypesForSelf(moduleName, abilityName, fileTypes); + if (ret != ERR_OK) { + APP_LOGE("SetAbilityFileTypesForSelf failed:%{public}d", ret); + BusinessErrorAni::ThrowCommonError( + env, ret, SET_ABILITY_FILE_TYPES_FOR_SELF, Constants::PERMISSION_MANAGE_SELF_SKILLS); + } +} + static ani_object QueryExtensionAbilityInfoNative(ani_env* env, ani_object aniWant, ani_enum_item aniExtensionAbilityType, ani_string aniExtensionAbilityTypeName, ani_double aniExtensionAbilityFlags, ani_double aniUserId, @@ -1167,6 +1197,8 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) reinterpret_cast(SetAbilityEnabledNative) }, ani_native_function { "setApplicationEnabledNative", nullptr, reinterpret_cast(SetApplicationEnabledNative) }, + ani_native_function { "setAbilityFileTypesForSelfNative", nullptr, + reinterpret_cast(SetAbilityFileTypesForSelfNative) }, ani_native_function { "getDynamicIconNative", nullptr, reinterpret_cast(GetDynamicIconNative) }, ani_native_function { "queryAbilityInfoWithWantsNative", nullptr, reinterpret_cast(QueryAbilityInfoWithWantsNative) }, diff --git a/interfaces/kits/ani/bundle_manager/ets/@ohos.bundle.bundleManager.ets b/interfaces/kits/ani/bundle_manager/ets/@ohos.bundle.bundleManager.ets index 1157bdc0f044ee3ac011f14985230ee3ebc30386..277fa5df6e3db0e352c8394f7aa294499e49396f 100644 --- a/interfaces/kits/ani/bundle_manager/ets/@ohos.bundle.bundleManager.ets +++ b/interfaces/kits/ani/bundle_manager/ets/@ohos.bundle.bundleManager.ets @@ -226,6 +226,8 @@ namespace bundleManager { export native function setApplicationEnabledNative(bundleName: string, isEnabled: boolean, appIndex: number, isSync: boolean): void; + export native function setAbilityFileTypesForSelfNative(moduleName: string, abilityName: string, fileTypes: Array): void; + export native function getDynamicIconNative(bundleName: string): string; export native function queryAbilityInfoWithWantsNative(wants: Array, abilityFlags: number, @@ -283,6 +285,10 @@ namespace bundleManager { return bundleManager.setApplicationEnabledNative(bundleName, isEnabled, 0, true); } + function setAbilityFileTypesForSelf(moduleName: string, abilityName: string, fileTypes: Array): void { + bundleManager.setAbilityFileTypesForSelfNative(moduleName, abilityName, fileTypes); + } + function queryExtensionAbilityInfoSync(want: Want, extensionAbilityType: ExtensionAbilityType, extensionAbilityFlags: number, userId?: number): Array { let userIdInfo: number = userId ?? EMPTY_USER_ID; diff --git a/interfaces/kits/js/bundle_manager/bundle_manager_helper.cpp b/interfaces/kits/js/bundle_manager/bundle_manager_helper.cpp index cefe5dbacd7c85be8ee1fae40cb7c7e4ace94011..e76c004fb7e6441a36feef89f85b4892fc482a58 100644 --- a/interfaces/kits/js/bundle_manager/bundle_manager_helper.cpp +++ b/interfaces/kits/js/bundle_manager/bundle_manager_helper.cpp @@ -446,6 +446,19 @@ ErrCode BundleManagerHelper::InnerGetAllPluginInfo( return CommonFunc::ConvertErrCode(ret); } +ErrCode BundleManagerHelper::InnerSetAbilityFileTypesForSelf( + const std::string& moduleName, const std::string& abilityName, const std::vector& fileTypes) +{ + auto bundleMgrProxy = CommonFunc::GetBundleMgr(); + if (bundleMgrProxy == nullptr) { + APP_LOGE("bundleMgrProxy null"); + return ERROR_BUNDLE_SERVICE_EXCEPTION; + } + ErrCode proxyRet = bundleMgrProxy->SetAbilityFileTypesForSelf(moduleName, abilityName, fileTypes); + APP_LOGI("SetAbilityFileTypesForSelf proxyRet:%{public}d", proxyRet); + return CommonFunc::ConvertErrCode(proxyRet); +} + ErrCode BundleManagerHelper::InnerGetAbilityInfos( const std::string& uri, uint32_t flags, std::vector& abilityInfos) { diff --git a/interfaces/kits/js/bundle_manager/bundle_manager_helper.h b/interfaces/kits/js/bundle_manager/bundle_manager_helper.h index 2498e8183278520b9c29472fdfbb47c72b3bbad2..32eb7b2d1e3df6eeddf1a25e0913a50f91f3964b 100644 --- a/interfaces/kits/js/bundle_manager/bundle_manager_helper.h +++ b/interfaces/kits/js/bundle_manager/bundle_manager_helper.h @@ -63,6 +63,8 @@ public: static ErrCode InnerGetRecoverableApplicationInfo(std::vector& recoverableApplications); static ErrCode InnerGetAllPluginInfo( std::string& hostBundleName, int32_t userId, std::vector& pluginBundleInfos); + static ErrCode InnerSetAbilityFileTypesForSelf( + const std::string& moduleName, const std::string& abilityName, const std::vector& fileTypes); static ErrCode InnerGetAbilityInfos(const std::string& uri, uint32_t flags, std::vector& abilityInfos); static ErrCode InnerCleanBundleCacheForSelfCallback(const OHOS::sptr cleanCacheCallback); }; diff --git a/interfaces/kits/js/bundle_manager/bundle_manager_sync.cpp b/interfaces/kits/js/bundle_manager/bundle_manager_sync.cpp index 3ae284ae5eb26f1ec9999a77d827b0f012f1a8dd..4391de32fad0deded23ea76aebd3dc3185e072a6 100644 --- a/interfaces/kits/js/bundle_manager/bundle_manager_sync.cpp +++ b/interfaces/kits/js/bundle_manager/bundle_manager_sync.cpp @@ -1057,5 +1057,53 @@ napi_value GetAppCloneIdentityBySandboxDataDirSync(napi_env env, napi_callback_i APP_LOGD("call GetAppCloneIdentityBySandboxDataDirSync done"); return nAppCloneIdentity; } + +napi_value SetAbilityFileTypesForSelf(napi_env env, napi_callback_info info) +{ + APP_LOGD("NAPI SetAbilityFileTypesForSelf begin"); + NapiArg args(env, info); + if (!args.Init(ARGS_SIZE_THREE, ARGS_SIZE_THREE)) { + APP_LOGE("param count invalid"); + BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR); + return nullptr; + } + std::string moduleName; + if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], moduleName)) { + APP_LOGE("parse moduleName failed"); + BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING); + return nullptr; + } + std::string abilityName; + if (!CommonFunc::ParseString(env, args[ARGS_POS_ONE], abilityName)) { + APP_LOGE("parse abilityName failed"); + BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, ABILITY_NAME, TYPE_STRING); + return nullptr; + } + std::vector fileTypes; + if (!CommonFunc::ParseStringArray(env, fileTypes, args[ARGS_POS_TWO])) { + APP_LOGE("parse fileTypes failed"); + BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, FILE_TYPES, TYPE_ARRAY); + return nullptr; + } + auto bundleMgrProxy = CommonFunc::GetBundleMgr(); + if (bundleMgrProxy == nullptr) { + APP_LOGE("bundleMgrProxy null"); + BusinessError::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION); + return nullptr; + } + ErrCode proxyRet = bundleMgrProxy->SetAbilityFileTypesForSelf(moduleName, abilityName, fileTypes); + APP_LOGI("SetAbilityFileTypesForSelf proxyRet:%{public}d", proxyRet); + ErrCode ret = CommonFunc::ConvertErrCode(proxyRet); + if (ret != ERR_OK) { + APP_LOGE("SetAbilityFileTypesForSelf failed:%{public}d", ret); + napi_value businessError = BusinessError::CreateCommonError( + env, ret, SET_ABILITY_FILE_TYPES_FOR_SELF, Constants::PERMISSION_MANAGE_SELF_SKILLS); + napi_throw(env, businessError); + return nullptr; + } + napi_value nRet = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &nRet)); + return nRet; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/kits/js/bundle_manager/bundle_manager_sync.h b/interfaces/kits/js/bundle_manager/bundle_manager_sync.h index 580a75f6d5e31aef548e8731280795f9fe78b628..fe1844d391c773ece167e723c43366d7938a73ad 100644 --- a/interfaces/kits/js/bundle_manager/bundle_manager_sync.h +++ b/interfaces/kits/js/bundle_manager/bundle_manager_sync.h @@ -49,6 +49,7 @@ napi_value GetAppProvisionInfoSync(napi_env env, napi_callback_info info); napi_value GetSignatureInfoSync(napi_env env, napi_callback_info info); napi_value GetSandboxDataDirSync(napi_env env, napi_callback_info info); napi_value GetAppCloneIdentityBySandboxDataDirSync(napi_env env, napi_callback_info info); +napi_value SetAbilityFileTypesForSelf(napi_env env, napi_callback_info info); bool ParseWantWithParameter(napi_env env, napi_value args, OHOS::AAFwk::Want &want); bool ParseWantListWithParameter(napi_env env, napi_value args, std::vector &wants); diff --git a/interfaces/kits/js/bundle_manager/native_module.cpp b/interfaces/kits/js/bundle_manager/native_module.cpp index bb8a742c84aca4454b299f6dfa762d8c50210625..f637e54f4a1fa071c6d6eabdfa4d3b62dfc5911e 100644 --- a/interfaces/kits/js/bundle_manager/native_module.cpp +++ b/interfaces/kits/js/bundle_manager/native_module.cpp @@ -183,6 +183,7 @@ static napi_value BundleManagerExport(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("getAppCloneIdentityBySandboxDataDir", GetAppCloneIdentityBySandboxDataDirSync), DECLARE_NAPI_FUNCTION("getAbilityInfo", GetAbilityInfos), DECLARE_NAPI_FUNCTION("getDynamicIconInfo", GetDynamicIconInfo), + DECLARE_NAPI_FUNCTION("setAbilityFileTypesForSelf", SetAbilityFileTypesForSelf), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); diff --git a/interfaces/kits/js/common/napi_constants.h b/interfaces/kits/js/common/napi_constants.h index 5054360c140b102a155857b99a6320a2764c7b9e..38f047a60aa62dfbd25d9e691e299f6fda3cc667 100644 --- a/interfaces/kits/js/common/napi_constants.h +++ b/interfaces/kits/js/common/napi_constants.h @@ -95,6 +95,7 @@ constexpr const char* GET_LAUNCH_WANT_FOR_BUNDLE_SYNC = "GetLaunchWantForBundleS constexpr const char* IS_ABILITY_ENABLED_SYNC = "IsAbilityEnabledSync"; constexpr const char* SET_ABILITY_ENABLED_SYNC = "SetAbilityEnabledSync"; constexpr const char* SET_APPLICATION_ENABLED_SYNC = "SetApplicationEnabledSync"; +constexpr const char* SET_ABILITY_FILE_TYPES_FOR_SELF = "SetAbilityFileTypesForSelf"; constexpr const char* GET_APP_CLONE_BUNDLE_INFO = "GetAppCloneBundleInfo"; constexpr const char* GET_DYNAMIC_ICON = "GetDynamicIcon"; constexpr const char* RESOURCE_NAME_OF_GET_SPECIFIED_DISTRIBUTION_TYPE = "GetSpecifiedDistributionType"; @@ -120,6 +121,7 @@ constexpr const char* SOURCE_PATHS = "sourcePaths"; constexpr const char* DESTINATION_PATH = "destinationPath"; constexpr const char* LINK = "link"; constexpr const char* URI = "uri"; +constexpr const char* FILE_TYPES = "fileTypes"; constexpr const char* SANDBOX_DATA_DIR = "sandboxDataDir"; constexpr const char* ERR_MSG_LAUNCH_WANT_INVALID = "The launch want is not found."; constexpr const char* PARAM_BUNDLENAME_EMPTY_ERROR = diff --git a/services/bundlemgr/include/base_bundle_installer.h b/services/bundlemgr/include/base_bundle_installer.h index 328a683b35914bd109dfa95fbde55c2a51324734..67e91d74578bd0fe278f6b50ae93bb504eca1eae 100644 --- a/services/bundlemgr/include/base_bundle_installer.h +++ b/services/bundlemgr/include/base_bundle_installer.h @@ -804,6 +804,7 @@ private: void SetFirstInstallTime(const std::string &bundleName, const int64_t &time, InnerBundleInfo &info); bool SaveFirstInstallBundleInfo(const std::string &bundleName, const int32_t userId, bool isPreInstallApp, const InnerBundleUserInfo &innerBundleUserInfo); + void UpdateDynamicSkills(); ErrCode MarkInstallFinish(); bool IsArkWeb(const std::string &bundleName) const; void UninstallDebugAppSandbox(const std::string &bundleName, const int32_t uid, diff --git a/services/bundlemgr/include/bundle_data_mgr.h b/services/bundlemgr/include/bundle_data_mgr.h index ca3a6466c7f6baf5466a32de34bbe7f7041b2bcc..79098ee8bde9c4206c4afdac7c33a83d2aee391b 100644 --- a/services/bundlemgr/include/bundle_data_mgr.h +++ b/services/bundlemgr/include/bundle_data_mgr.h @@ -513,6 +513,8 @@ public: */ ErrCode SetAbilityEnabled(const AbilityInfo &abilityInfo, int32_t appIndex, bool isEnabled, int32_t userId = Constants::UNSPECIFIED_USERID); + ErrCode SetAbilityFileTypes(const std::string &bundleName, const std::string &moduleName, + const std::string &abilityName, const std::vector &fileTypes); /** * @brief Register the bundle status callback function. * @param bundleStatusCallback Indicates the callback object that using for notifing the bundle status. diff --git a/services/bundlemgr/include/bundle_mgr_host_impl.h b/services/bundlemgr/include/bundle_mgr_host_impl.h index bf143ebfa942ef65beabb2c44d450bd1b9c88fe1..9c9335c2e9972b652da52f5e712d2d811e839da3 100644 --- a/services/bundlemgr/include/bundle_mgr_host_impl.h +++ b/services/bundlemgr/include/bundle_mgr_host_impl.h @@ -723,6 +723,8 @@ public: */ virtual ErrCode SetCloneAbilityEnabled(const AbilityInfo &abilityInfo, int32_t appIndex, bool isEnabled, int32_t userId = Constants::UNSPECIFIED_USERID) override; + virtual ErrCode SetAbilityFileTypesForSelf(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes) override; /** * @brief Obtains the interface used to install and uninstall bundles. * @return Returns a pointer to IBundleInstaller class if exist; returns nullptr otherwise. diff --git a/services/bundlemgr/include/bundle_service_constants.h b/services/bundlemgr/include/bundle_service_constants.h index 3b3cbebcfc5343c12dd17487dfbafe021cee4a30..9f35ef6a82a7208b8847f6699a713fc1636b939c 100644 --- a/services/bundlemgr/include/bundle_service_constants.h +++ b/services/bundlemgr/include/bundle_service_constants.h @@ -71,6 +71,7 @@ constexpr const char* BASE = "/base/"; constexpr const char* CLONE = "clone"; constexpr const char* PLUS_SIGN = "+"; constexpr const char* MINUS_SIGN = "-"; +constexpr const char* DOT_SIGN = "."; constexpr const char* DATABASE = "/database/"; constexpr const char* SHAREFILES = "/sharefiles/"; constexpr const char* LOG = "/log/"; @@ -148,6 +149,9 @@ constexpr const char* PERMISSION_SUPPORT_PLUGIN = "ohos.permission.kernel.SUPPOR constexpr const char* PERMISSION_MANAGE_STORAGE = "ohos.permission.atomicService.MANAGE_STORAGE"; constexpr const char* FLAG_HOME_INTENT_FROM_SYSTEM = "flag.home.intent.from.system"; +constexpr const char* ACTION_VIEW_DATA = "ohos.want.action.viewData"; +constexpr const char* FILE = "file"; +constexpr const char* FILE_OPEN = "FileOpen"; // max number of haps under one direction constexpr uint8_t MAX_HAP_NUMBER = 128; constexpr const char* DATA_ABILITY_URI_PREFIX = "dataability://"; diff --git a/services/bundlemgr/include/bundle_util.h b/services/bundlemgr/include/bundle_util.h index 78e90e93b24d0a234e0a0bf507e55deaa42cd1ec..aefbbe75010eec401cdad6240435a9597f212336 100644 --- a/services/bundlemgr/include/bundle_util.h +++ b/services/bundlemgr/include/bundle_util.h @@ -217,6 +217,8 @@ public: static void MakeFsConfig(const std::string &bundleName, const std::string &configPath, const std::string labelValue, const std::string labelPath); static void RemoveFsConfig(const std::string &bundleName, const std::string &configPath); + static std::string GetAbilityKey( + const std::string &bundleName, const std::string &moduleName, const std::string &abilityName); static std::string CreateInstallTempDir(uint32_t installerId, const DirType &type); static std::string CreateSharedBundleTempDir(uint32_t installerId, uint32_t index); static int32_t CreateFileDescriptor(const std::string &bundlePath, long long offset); diff --git a/services/bundlemgr/include/inner_bundle_info.h b/services/bundlemgr/include/inner_bundle_info.h index 7149c3d2f05f3c7ec528c7937dc3404ff0bad124..07ced94d8781406b9738ecd88907a2ede92dd91e 100644 --- a/services/bundlemgr/include/inner_bundle_info.h +++ b/services/bundlemgr/include/inner_bundle_info.h @@ -1316,10 +1316,12 @@ public: /** * @brief Obtains all skillInfos. */ - const std::map> &GetInnerSkillInfos() const - { - return skillInfos_; - } + std::map> GetInnerSkillInfos() const; + void UpdateDynamicSkills(); + ErrCode SetAbilityFileTypes(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes); + bool ValidateDynamicSkills(const std::map> &dynamicAbilitySkills) const; + void AppendDynamicSkillsIfExist(AbilityInfo &abilityInfo) const; /** * @brief Fetch all extensionAbilityInfos, can be modify. */ @@ -2441,6 +2443,7 @@ private: std::map baseAbilityInfos_; std::map> skillInfos_; + std::map> dynamicAbilitySkills_; std::map innerBundleUserInfos_; std::map baseExtensionInfos_; diff --git a/services/bundlemgr/src/base_bundle_installer.cpp b/services/bundlemgr/src/base_bundle_installer.cpp index a0b436a0e3a3438812be1a3dd5f36f21a0705383..862d8b263286157f876706e93148f0cfb9fa0f4c 100644 --- a/services/bundlemgr/src/base_bundle_installer.cpp +++ b/services/bundlemgr/src/base_bundle_installer.cpp @@ -1558,6 +1558,7 @@ ErrCode BaseBundleInstaller::ProcessBundleInstall(const std::vector RemoveOldExtensionDirs(); /* process quick fix when install new moudle */ ProcessQuickFixWhenInstallNewModule(installParam, newInfos); + UpdateDynamicSkills(); VerifyDomain(); PatchDataMgr::GetInstance().ProcessPatchInfo(bundleName_, inBundlePaths, newInfos.begin()->second.GetVersionCode(), AppPatchType::INTERNAL, installParam.isPatch); @@ -6683,6 +6684,16 @@ void BaseBundleInstaller::PrepareSkillUri(const std::vector &skills, } #endif +void BaseBundleInstaller::UpdateDynamicSkills() +{ + InnerBundleInfo info; + if (!GetTempBundleInfo(info)) { + LOG_E(BMS_TAG_INSTALLER, "GetTempBundleInfo failed, bundleName: %{public}s", bundleName_.c_str()); + return; + } + info.UpdateDynamicSkills(); +} + void BaseBundleInstaller::VerifyDomain() { #ifdef APP_DOMAIN_VERIFY_ENABLED diff --git a/services/bundlemgr/src/bundle_data_mgr.cpp b/services/bundlemgr/src/bundle_data_mgr.cpp index 3018b073110524839ac11044ea3e649d31165a74..8f0c3d001a4f317b6a1384c993c3792451481b6b 100644 --- a/services/bundlemgr/src/bundle_data_mgr.cpp +++ b/services/bundlemgr/src/bundle_data_mgr.cpp @@ -1294,6 +1294,8 @@ bool BundleDataMgr::QueryAbilityInfoWithFlags(const std::optional & } if ((static_cast(flags) & GET_ABILITY_INFO_WITH_SKILL) != GET_ABILITY_INFO_WITH_SKILL) { info.skills.clear(); + } else { + innerBundleInfo.AppendDynamicSkillsIfExist(info); } if ((static_cast(flags) & GET_ABILITY_INFO_WITH_APPLICATION) == GET_ABILITY_INFO_WITH_APPLICATION) { innerBundleInfo.GetApplicationInfo( @@ -1362,6 +1364,8 @@ ErrCode BundleDataMgr::QueryAbilityInfoWithFlagsV9(const std::optional(flags) & static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL)) != static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL)) { info.skills.clear(); + } else { + innerBundleInfo.AppendDynamicSkillsIfExist(info); } if ((static_cast(flags) & static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION)) == static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION)) { @@ -1672,7 +1676,7 @@ void BundleDataMgr::GetMatchAbilityInfos(const Want &want, int32_t flags, const if (CheckAbilityInfoFlagExist(flags, GET_ABILITY_INFO_SYSTEMAPP_ONLY) && !info.IsSystemApp()) { return; } - const std::map> &skillInfos = info.GetInnerSkillInfos(); + const std::map> skillInfos = info.GetInnerSkillInfos(); for (const auto &abilityInfoPair : info.GetInnerAbilityInfos()) { bool isPrivateType = MatchPrivateType( want, abilityInfoPair.second.supportExtNames, abilityInfoPair.second.supportMimeTypes, paramMimeTypes); @@ -1706,6 +1710,8 @@ void BundleDataMgr::GetMatchAbilityInfos(const Want &want, int32_t flags, const } if (!CheckAbilityInfoFlagExist(flags, GET_ABILITY_INFO_WITH_SKILL)) { abilityinfo.skills.clear(); + } else { + info.AppendDynamicSkillsIfExist(abilityinfo); } if (CheckAbilityInfoFlagExist(flags, GET_ABILITY_INFO_WITH_SKILL_URI)) { AddSkillUrisInfo(skillsPair->second, abilityinfo.skillUri, skillIndex, matchUriIndex); @@ -1778,6 +1784,8 @@ void BundleDataMgr::EmplaceAbilityInfo(const InnerBundleInfo &info, const std::v static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL)) != static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL)) { abilityInfo.skills.clear(); + } else { + info.AppendDynamicSkillsIfExist(abilityInfo); } if ((static_cast(flags) & static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL_URI)) == @@ -1808,7 +1816,7 @@ void BundleDataMgr::GetMatchAbilityInfosV9(const Want &want, int32_t flags, cons LOG_W(BMS_TAG_QUERY, "target not system app"); return; } - const std::map> &skillInfos = info.GetInnerSkillInfos(); + const std::map> skillInfos = info.GetInnerSkillInfos(); for (const auto &abilityInfoPair : info.GetInnerAbilityInfos()) { AbilityInfo abilityinfo = InnerAbilityInfo::ConvertToAbilityInfo(abilityInfoPair.second); auto skillsPair = skillInfos.find(abilityInfoPair.first); @@ -2042,7 +2050,7 @@ void BundleDataMgr::GetMultiLauncherAbilityInfo(const Want& want, int64_t installTime, std::vector& abilityInfos) const { int32_t count = 0; - const std::map> &skillInfos = info.GetInnerSkillInfos(); + const std::map> skillInfos = info.GetInnerSkillInfos(); for (const auto& abilityInfoPair : info.GetInnerAbilityInfos()) { auto skillsPair = skillInfos.find(abilityInfoPair.first); if (skillsPair == skillInfos.end()) { @@ -5043,6 +5051,27 @@ ErrCode BundleDataMgr::SetAbilityEnabled(const AbilityInfo &abilityInfo, int32_t return ERR_OK; } +ErrCode BundleDataMgr::SetAbilityFileTypes(const std::string &bundleName, const std::string &moduleName, + const std::string &abilityName, const std::vector &fileTypes) +{ + std::unique_lock lock(bundleInfoMutex_); + auto item = bundleInfos_.find(bundleName); + if (item == bundleInfos_.end()) { + APP_LOGE("-n %{public}s not exist", bundleName.c_str()); + return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST; + } + ErrCode ret = item->second.SetAbilityFileTypes(moduleName, abilityName, fileTypes); + if (ret != ERR_OK) { + APP_LOGE("SetAbilityFileTypes failed:%{public}d", ret); + return ret; + } + if (!dataStorage_->SaveStorageBundleInfo(item->second)) { + APP_LOGE("SaveStorageBundleInfo failed"); + return ERR_BUNDLE_MANAGER_INTERNAL_ERROR; + } + return ERR_OK; +} + std::shared_ptr BundleDataMgr::GetSandboxAppHelper() const { return sandboxAppHelper_; diff --git a/services/bundlemgr/src/bundle_mgr_host_impl.cpp b/services/bundlemgr/src/bundle_mgr_host_impl.cpp index f841ca40e80f5da75840b24ebffb7ed95d6b32fc..a67c922004024bd1381e16663866acda5d03f313 100644 --- a/services/bundlemgr/src/bundle_mgr_host_impl.cpp +++ b/services/bundlemgr/src/bundle_mgr_host_impl.cpp @@ -37,6 +37,7 @@ #include "ipc_skeleton.h" #include "iservice_registry.h" #include "on_demand_install_data_mgr.h" +#include "param_validator.h" #include "system_ability_helper.h" #include "inner_bundle_clone_common.h" #ifdef DEVICE_USAGE_STATISTICS_ENABLED @@ -83,7 +84,6 @@ const std::string AUTH_TITLE = " "; const std::string BUNDLE_NAME = "bundleName"; const std::string LABEL = "label"; const std::string NEW_LINE = "\n"; -const std::string ACTION_VIEW_DATA = "ohos.want.action.viewData"; const std::string RESOURCE_NOT_SUPPORT = "warning: dump label failed due to the device not supporting bundle resource!"; const std::string FILE_URI = "file"; @@ -2835,6 +2835,39 @@ ErrCode BundleMgrHostImpl::SetCloneAbilityEnabled(const AbilityInfo &abilityInfo return ERR_OK; } +ErrCode BundleMgrHostImpl::SetAbilityFileTypesForSelf(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes) +{ + LOG_I(BMS_TAG_QUERY, "SetAbilityFileTypesForSelf -m:%{public}s, -a:%{public}s", + moduleName.c_str(), abilityName.c_str()); + if (!ParamValidator::ValidateAbilityFileTypes(moduleName, abilityName, fileTypes)) { + LOG_E(BMS_TAG_QUERY, "invalid params"); + return ERR_BUNDLE_MANAGER_PARAM_ERROR; + } + + if (!BundlePermissionMgr::IsSystemApp()) { + LOG_E(BMS_TAG_QUERY, "non-system app calling system api"); + return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED; + } + if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_MANAGE_SELF_SKILLS)) { + LOG_E(BMS_TAG_QUERY, "permission denied"); + return ERR_BUNDLE_MANAGER_PERMISSION_DENIED; + } + + auto dataMgr = GetDataMgrFromService(); + if (dataMgr == nullptr) { + LOG_E(BMS_TAG_QUERY, "dataMgr is nullptr"); + return ERR_BUNDLE_MANAGER_INTERNAL_ERROR; + } + std::string bundleName; + ErrCode ret = dataMgr->GetNameForUid(IPCSkeleton::GetCallingUid(), bundleName); + if (ret != ERR_OK) { + LOG_E(BMS_TAG_QUERY, "GetNameForUid failed:%{public}d", ret); + return ERR_BUNDLE_MANAGER_INTERNAL_ERROR; + } + return dataMgr->SetAbilityFileTypes(bundleName, moduleName, abilityName, fileTypes); +} + sptr BundleMgrHostImpl::GetBundleInstaller() { HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr); @@ -6196,7 +6229,7 @@ ErrCode BundleMgrHostImpl::ImplicitQueryAbilityInfosWithDefault(const std::strin } Want want; want.SetType(normalizedType); - want.SetAction(ACTION_VIEW_DATA); + want.SetAction(ServiceConstants::ACTION_VIEW_DATA); want.SetUri(FILE_URI); int32_t abilityInfoflags = static_cast(GetAbilityInfoFlag::GET_ABILITY_INFO_DEFAULT); auto uid = IPCSkeleton::GetCallingUid(); diff --git a/services/bundlemgr/src/bundle_util.cpp b/services/bundlemgr/src/bundle_util.cpp index c2d4647e52c4746efd11ff1ef63bfe3dc9b26984..2230eb4bee59e8c8a9b0138b44bc16dc46d87c6c 100644 --- a/services/bundlemgr/src/bundle_util.cpp +++ b/services/bundlemgr/src/bundle_util.cpp @@ -396,6 +396,12 @@ void BundleUtil::RemoveFsConfig(const std::string &bundleName, const std::string } } +std::string BundleUtil::GetAbilityKey( + const std::string &bundleName, const std::string &moduleName, const std::string &abilityName) +{ + return bundleName + ServiceConstants::DOT_SIGN + moduleName + ServiceConstants::DOT_SIGN + abilityName; +} + std::string BundleUtil::CreateTempDir(const std::string &tempDir) { if (!OHOS::ForceCreateDirectory(tempDir)) { diff --git a/services/bundlemgr/src/default_app/default_app_mgr.cpp b/services/bundlemgr/src/default_app/default_app_mgr.cpp index 7e28ac4f212ec14ce12f80e7ab97d9be6161052e..16f657921b924a16d7ec424960bc4d0efb23bcf5 100644 --- a/services/bundlemgr/src/default_app/default_app_mgr.cpp +++ b/services/bundlemgr/src/default_app/default_app_mgr.cpp @@ -58,7 +58,6 @@ constexpr const char* WORD = "WORD"; constexpr const char* EXCEL = "EXCEL"; constexpr const char* PPT = "PPT"; constexpr const char* EMAIL = "EMAIL"; -constexpr const char* ACTION_VIEW_DATA = "ohos.want.action.viewData"; constexpr const char* APP_TYPES_KEY[] = { IMAGE, AUDIO, VIDEO, PDF, WORD, EXCEL, PPT }; @@ -421,7 +420,7 @@ void DefaultAppMgr::HandleRemoveUser(int32_t userId) const bool DefaultAppMgr::IsBrowserWant(const Want& want) const { - bool matchAction = want.GetAction() == ACTION_VIEW_DATA; + bool matchAction = want.GetAction() == ServiceConstants::ACTION_VIEW_DATA; if (!matchAction) { LOG_D(BMS_TAG_DEFAULT, "Action does not match, not browser want"); return false; @@ -461,7 +460,7 @@ std::string DefaultAppMgr::GetTypeFromWant(const Want& want) const if (IsEmailWant(want)) { return EMAIL; } - if (want.GetAction() != ACTION_VIEW_DATA) { + if (want.GetAction() != ServiceConstants::ACTION_VIEW_DATA) { return Constants::EMPTY_STRING; } std::string uri = Skill::GetOptParamUri(want.GetUriString()); @@ -674,7 +673,7 @@ bool DefaultAppMgr::MatchAppType(const std::string& type, const std::vector& skills) const { LOG_D(BMS_TAG_DEFAULT, "begin to verify browser skills"); Want httpWant; - httpWant.SetAction(ACTION_VIEW_DATA); + httpWant.SetAction(ServiceConstants::ACTION_VIEW_DATA); httpWant.AddEntity(ENTITY_BROWSER); httpWant.SetUri(HTTP); Want httpsWant; - httpsWant.SetAction(ACTION_VIEW_DATA); + httpsWant.SetAction(ServiceConstants::ACTION_VIEW_DATA); httpsWant.AddEntity(ENTITY_BROWSER); httpsWant.SetUri(HTTPS); for (const Skill& skill : skills) { @@ -723,7 +722,7 @@ bool DefaultAppMgr::IsEmailSkillsValid(const std::vector& skills) const bool DefaultAppMgr::MatchUtd(const std::string& utd, const std::vector& skills) const { LOG_D(BMS_TAG_DEFAULT, "utd : %{public}s", utd.c_str()); - if (MatchActionAndType(ACTION_VIEW_DATA, utd, skills)) { + if (MatchActionAndType(ServiceConstants::ACTION_VIEW_DATA, utd, skills)) { return true; } LOG_E(BMS_TAG_DEFAULT, "match utd failed"); diff --git a/services/bundlemgr/src/inner_bundle_info.cpp b/services/bundlemgr/src/inner_bundle_info.cpp index 9f5713b3ffec1ada446b807c15b714c54247d665..b678984d13cd46feb2306bdfdfab716985ad0cb4 100644 --- a/services/bundlemgr/src/inner_bundle_info.cpp +++ b/services/bundlemgr/src/inner_bundle_info.cpp @@ -41,6 +41,7 @@ constexpr const char* BASE_BUNDLE_INFO = "baseBundleInfo"; constexpr const char* BASE_ABILITY_INFO = "baseAbilityInfos"; constexpr const char* INNER_MODULE_INFO = "innerModuleInfos"; constexpr const char* SKILL_INFOS = "skillInfos"; +constexpr const char* DYNAMIC_ABILITY_SKILLS = "dynamicAbilitySkills"; constexpr const char* USER_ID = "userId_"; constexpr const char* APP_FEATURE = "appFeature"; constexpr const char* NAME = "name"; @@ -344,6 +345,7 @@ InnerBundleInfo &InnerBundleInfo::operator=(const InnerBundleInfo &info) this->shortcutInfos_ = info.shortcutInfos_; this->baseAbilityInfos_ = info.baseAbilityInfos_; this->skillInfos_ = info.skillInfos_; + this->dynamicAbilitySkills_ = info.dynamicAbilitySkills_; this->innerBundleUserInfos_ = info.innerBundleUserInfos_; this->bundlePackInfo_ = std::make_shared(); if (info.bundlePackInfo_ != nullptr) { @@ -528,6 +530,7 @@ void InnerBundleInfo::ToJson(nlohmann::json &jsonObject) const jsonObject[INNER_MODULE_INFO] = innerModuleInfos_; jsonObject[INNER_SHARED_MODULE_INFO] = innerSharedModuleInfos_; jsonObject[SKILL_INFOS] = skillInfos_; + jsonObject[DYNAMIC_ABILITY_SKILLS] = dynamicAbilitySkills_; jsonObject[USER_ID] = userId_; jsonObject[APP_FEATURE] = appFeature_; jsonObject[MODULE_FORMS] = formInfos_; @@ -1388,6 +1391,14 @@ int32_t InnerBundleInfo::FromJson(const nlohmann::json &jsonObject) true, parseResult, ArrayType::NOT_ARRAY); + GetValueIfFindKey>>(jsonObject, + jsonObjectEnd, + DYNAMIC_ABILITY_SKILLS, + dynamicAbilitySkills_, + JsonType::OBJECT, + false, + parseResult, + ArrayType::NOT_ARRAY); GetValueIfFindKey(jsonObject, jsonObjectEnd, USER_ID, @@ -1817,6 +1828,111 @@ std::optional InnerBundleInfo::FindExtensionInfo( return std::nullopt; } +std::map> InnerBundleInfo::GetInnerSkillInfos() const +{ + std::map> mergedSkills = skillInfos_; + for (const auto &[key, dynamicSkills] : dynamicAbilitySkills_) { + mergedSkills[key].insert(mergedSkills[key].end(), dynamicSkills.begin(), dynamicSkills.end()); + } + return mergedSkills; +} + +void InnerBundleInfo::UpdateDynamicSkills() +{ + for (auto item = dynamicAbilitySkills_.begin(); item != dynamicAbilitySkills_.end();) { + if (baseAbilityInfos_.find(item->first) == baseAbilityInfos_.end()) { + item = dynamicAbilitySkills_.erase(item); + } else { + ++item; + } + } +} + +void InnerBundleInfo::AppendDynamicSkillsIfExist(AbilityInfo &abilityInfo) const +{ + if (dynamicAbilitySkills_.empty()) { + return; + } + std::string abilityKey = BundleUtil::GetAbilityKey( + abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name); + auto item = dynamicAbilitySkills_.find(abilityKey); + if (item != dynamicAbilitySkills_.end()) { + abilityInfo.skills.insert(abilityInfo.skills.end(), item->second.begin(), item->second.end()); + } +} + +bool InnerBundleInfo::ValidateDynamicSkills(const std::map> &dynamicAbilitySkills) const +{ + try { + // to json test + nlohmann::json jsonObject; + jsonObject[DYNAMIC_ABILITY_SKILLS] = dynamicAbilitySkills; + (void)jsonObject.dump(); + // from json test + const auto &jsonObjectEnd = jsonObject.end(); + int32_t ret = ERR_OK; + std::map> tmpDynamicAbilitySkills; + GetValueIfFindKey>>(jsonObject, + jsonObjectEnd, + DYNAMIC_ABILITY_SKILLS, + tmpDynamicAbilitySkills, + JsonType::OBJECT, + false, + ret, + ArrayType::NOT_ARRAY); + if (ret != ERR_OK) { + APP_LOGE("ValidateDynamicSkills error:%{public}d", ret); + return false; + } + } catch (const nlohmann::json::exception& e) { + APP_LOGE("ValidateDynamicSkills exception:%{public}s, %{public}d", e.what(), e.id); + return false; + } + return true; +} + +ErrCode InnerBundleInfo::SetAbilityFileTypes(const std::string &moduleName, const std::string &abilityName, + const std::vector &fileTypes) +{ + auto moduleInfo = innerModuleInfos_.find(moduleName); + if (moduleInfo == innerModuleInfos_.end()) { + APP_LOGE("-m %{public}s not exist", moduleName.c_str()); + return ERR_BUNDLE_MANAGER_MODULE_NOT_EXIST; + } + std::string abilityKey = BundleUtil::GetAbilityKey(GetBundleName(), moduleName, abilityName); + auto item = baseAbilityInfos_.find(abilityKey); + if (item == baseAbilityInfos_.end()) { + APP_LOGE("-a %{public}s not exist", abilityName.c_str()); + return ERR_BUNDLE_MANAGER_ABILITY_NOT_EXIST; + } + if (moduleName != item->second.moduleName || abilityName != item->second.name) { + APP_LOGE("-a %{public}s not exist", abilityName.c_str()); + return ERR_BUNDLE_MANAGER_ABILITY_NOT_EXIST; + } + + std::vector skills; + Skill skill; + skill.actions = {ServiceConstants::ACTION_VIEW_DATA}; + for (const std::string &fileType : fileTypes) { + SkillUri skillUri; + skillUri.scheme = ServiceConstants::FILE; + skillUri.type = fileType; + skillUri.linkFeature = ServiceConstants::FILE_OPEN; + skill.uris.emplace_back(skillUri); + } + skills.emplace_back(skill); + + std::map> tmpDynamicSkills; + tmpDynamicSkills[abilityKey] = skills; + if (!ValidateDynamicSkills(tmpDynamicSkills)) { + APP_LOGE("ValidateDynamicSkills failed"); + return ERR_BUNDLE_MANAGER_PARAM_ERROR; + } + + dynamicAbilitySkills_[abilityKey] = skills; + return ERR_OK; +} + bool InnerBundleInfo::AddModuleInfo(const InnerBundleInfo &newInfo) { if (newInfo.currentPackage_.empty()) { @@ -2829,6 +2945,8 @@ void InnerBundleInfo::GetBundleWithAbilitiesV9( if ((static_cast(flags) & static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SKILL)) != static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SKILL)) { abilityInfo.skills.clear(); + } else { + AppendDynamicSkillsIfExist(abilityInfo); } hapModuleInfo.abilityInfos.emplace_back(abilityInfo); @@ -2882,6 +3000,8 @@ void InnerBundleInfo::GetBundleWithAbilities( abilityInfo.enabled = isEnabled; if ((static_cast(flags) & GET_BUNDLE_WITH_SKILL) != GET_BUNDLE_WITH_SKILL) { abilityInfo.skills.clear(); + } else { + AppendDynamicSkillsIfExist(abilityInfo); } abilityInfo.appIndex = appIndex; bundleInfo.abilityInfos.emplace_back(abilityInfo);