已开启
常驻应用按需拉起支持SA #20370
zhangtao创建于 4 天前
常驻应用按需拉起支持SA #20370
已开启
共 12 个文件变更+344-15
| @@ -154,7 +154,32 @@ public: | |||
| 154 | * @return An integer indicating the result of the operation (e.g., success or error code). | 154 | * @return An integer indicating the result of the operation (e.g., success or error code). |
| 155 | */ | 155 | */ |
| 156 | int32_t GetResidentProcessRawData(const std::string &bundleName, const std::string &callerName); | 156 | int32_t GetResidentProcessRawData(const std::string &bundleName, const std::string &callerName); |
| 157 | + | ||
| 158 | + /** | ||
| 159 | + * @brief Verifies the sa configuration permissions for the specified bundle. | ||
| 160 | + * @param bundleName The name of the bundle to verify. | ||
| 161 | + * @param callerUid The uid of the sa caller making the verification request. | ||
| 162 | + * @return Returns 0 on success, non-zero on failure. | ||
| 163 | + */ | ||
| 164 | + int32_t VerifySaConfigurationPermissions(const std::string &bundleName, int32_t callerUid); | ||
| 165 | + | ||
| 166 | + /** | ||
| 167 | + * @brief Retrieves raw data of sa configuration permissions for a resident process. | ||
| 168 | + * | ||
| 169 | + * @param bundleName The name of the bundle associated with the resident process. | ||
| 170 | + * @param callerUid The uid of the sa caller requesting the resident process data. | ||
| 171 | + * @return An integer indicating the result of the operation (e.g., success or error code). | ||
| 172 | + */ | ||
| 173 | + int32_t GetSaResidentProcessRawData(const std::string &bundleName, int32_t callerUid); | ||
| 157 | private: | 174 | private: |
| 175 | + /* | ||
| 176 | + * Verify callerUid against the sa uid list which is stored as a JSON array text. | ||
| 177 | + * Elements are compared exactly one by one; substring match is forbidden | ||
| 178 | + * ("305" must not match "3057"). A legacy db without the column reports a read | ||
| 179 | + * failure and is treated as an empty list (deny). | ||
| 180 | + */ | ||
| 181 | + bool VerifyUidInJsonArray(const std::string &jsonArrayText, int32_t callerUid); | ||
| 182 | + | ||
| 158 | // Pointer to the RDB data manager, responsible for managing RDB operations. | 183 | // Pointer to the RDB data manager, responsible for managing RDB operations. |
| 159 | std::unique_ptr<RdbDataManager> rdbMgr_ = nullptr; | 184 | std::unique_ptr<RdbDataManager> rdbMgr_ = nullptr; |
| 160 | }; | 185 | }; |
| @@ -26,15 +26,16 @@ namespace AbilityRuntime { | |||
| 26 | class ParserUtil final { | 26 | class ParserUtil final { |
| 27 | public: | 27 | public: |
| 28 | static ParserUtil &GetInstance(); | 28 | static ParserUtil &GetInstance(); |
| 29 | - void GetResidentProcessRawData(std::vector<std::tuple<std::string, std::string, std::string>> &list); | 29 | + void GetResidentProcessRawData( |
| 30 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> &list); | ||
| 30 | 31 | ||
| 31 | private: | 32 | private: |
| 32 | - void ParsePreInstallAbilityConfig( | 33 | + void ParsePreInstallAbilityConfig(const std::string &filePath, |
| 33 | - const std::string &filePath, std::vector<std::tuple<std::string, std::string, std::string>> &list); | 34 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> &list); |
| 34 | void GetPreInstallRootDirList(std::vector<std::string> &rootDirList); | 35 | void GetPreInstallRootDirList(std::vector<std::string> &rootDirList); |
| 35 | bool ReadFileIntoJson(const std::string &filePath, nlohmann::json &jsonBuf); | 36 | bool ReadFileIntoJson(const std::string &filePath, nlohmann::json &jsonBuf); |
| 36 | - bool FilterInfoFromJson( | 37 | + bool FilterInfoFromJson(nlohmann::json &jsonBuf, |
| 37 | - nlohmann::json &jsonBuf, std::vector<std::tuple<std::string, std::string, std::string>> &list); | 38 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> &list); |
| 38 | }; | 39 | }; |
| 39 | } // namespace AbilityRuntime | 40 | } // namespace AbilityRuntime |
| 40 | } // namespace OHOS | 41 | } // namespace OHOS |
| @@ -67,6 +67,16 @@ public: | |||
| 67 | */ | 67 | */ |
| 68 | int32_t SetResidentProcessEnabled(const std::string &bundleName, const std::string &callerName, bool updateEnable); | 68 | int32_t SetResidentProcessEnabled(const std::string &bundleName, const std::string &callerName, bool updateEnable); |
| 69 | 69 | ||
| 70 | + /** | ||
| 71 | + * Set the enable flag for resident processes by sa caller. | ||
| 72 | + * | ||
| 73 | + * @param bundleName, The bundle name of the resident process. | ||
| 74 | + * @param callerUid, The uid of the sa caller, which must be in the sa uid list of the bundle. | ||
| 75 | + * @param updateEnable, Set value, if true, start the resident process, If false, stop the resident process | ||
| 76 | + * @return Returns ERR_OK on success, others on failure. | ||
| 77 | + */ | ||
| 78 | + int32_t SetResidentProcessEnabledForSA(const std::string &bundleName, int32_t callerUid, bool updateEnable); | ||
| 79 | + | ||
| 70 | /** | 80 | /** |
| 71 | * start empty resident processes. | 81 | * start empty resident processes. |
| 72 | * | 82 | * |
| @@ -96,6 +106,7 @@ public: | |||
| 96 | bool GetResidentBundleInfosForUser(std::vector<AppExecFwk::BundleInfo> &bundleInfos, int32_t userId); | 106 | bool GetResidentBundleInfosForUser(std::vector<AppExecFwk::BundleInfo> &bundleInfos, int32_t userId); |
| 97 | void StartFailedResidentAbilities(); | 107 | void StartFailedResidentAbilities(); |
| 98 | private: | 108 | private: |
| 109 | + int32_t SetResidentProcessEnabledInner(const std::string &bundleName, bool updateEnable); | ||
| 99 | void UpdateResidentProcessesStatus(const std::string &bundleName, bool localEnable, bool updateEnable); | 110 | void UpdateResidentProcessesStatus(const std::string &bundleName, bool localEnable, bool updateEnable); |
| 100 | void AddFailedResidentAbility(const std::string &bundleName, const std::string &abilityName, int32_t userId); | 111 | void AddFailedResidentAbility(const std::string &bundleName, const std::string &abilityName, int32_t userId); |
| 101 | void StartResidentProcessWithMainElementPerBundle(const AppExecFwk::BundleInfo &bundleInfo, | 112 | void StartResidentProcessWithMainElementPerBundle(const AppExecFwk::BundleInfo &bundleInfo, |
| @@ -16173,6 +16173,13 @@ void AbilityManagerService::CloseAssertDialog(const std::string &assertSessionId | |||
| 16173 | int32_t AbilityManagerService::SetResidentProcessEnabled(const std::string &bundleName, bool enable) | 16173 | int32_t AbilityManagerService::SetResidentProcessEnabled(const std::string &bundleName, bool enable) |
| 16174 | { | 16174 | { |
| 16175 | TAG_LOGD(AAFwkTag::ABILITYMGR, "called"); | 16175 | TAG_LOGD(AAFwkTag::ABILITYMGR, "called"); |
| 16176 | + if (AAFwk::PermissionVerification::GetInstance()->IsSACall()) { | ||
| 16177 | + auto residentProcessManager = DelayedSingleton<ResidentProcessManager>::GetInstance(); | ||
| 16178 | + CHECK_POINTER_AND_RETURN(residentProcessManager, INNER_ERR); | ||
| 16179 | + return residentProcessManager->SetResidentProcessEnabledForSA(bundleName, | ||
| 16180 | + static_cast<int32_t>(IPCSkeleton::GetCallingUid()), enable); | ||
| 16181 | + } | ||
| 16182 | + | ||
| 16176 | if (!AAFwk::PermissionVerification::GetInstance()->IsSystemAppCall()) { | 16183 | if (!AAFwk::PermissionVerification::GetInstance()->IsSystemAppCall()) { |
| 16177 | TAG_LOGE(AAFwkTag::ABILITYMGR, "permission verification failed"); | 16184 | TAG_LOGE(AAFwkTag::ABILITYMGR, "permission verification failed"); |
| 16178 | return ERR_NOT_SYSTEM_APP; | 16185 | return ERR_NOT_SYSTEM_APP; |
| @@ -27,10 +27,12 @@ const std::string ABILITY_RDB_TABLE_NAME = "resident_process_list"; | |||
| 27 | const std::string KEY_BUNDLE_NAME = "KEY_BUNDLE_NAME"; | 27 | const std::string KEY_BUNDLE_NAME = "KEY_BUNDLE_NAME"; |
| 28 | const std::string KEY_KEEP_ALIVE_ENABLE = "KEEP_ALIVE_ENABLE"; | 28 | const std::string KEY_KEEP_ALIVE_ENABLE = "KEEP_ALIVE_ENABLE"; |
| 29 | const std::string KEY_KEEP_ALIVE_CONFIGURED_LIST = "KEEP_ALIVE_CONFIGURED_LIST"; | 29 | const std::string KEY_KEEP_ALIVE_CONFIGURED_LIST = "KEEP_ALIVE_CONFIGURED_LIST"; |
| 30 | +const std::string KEY_KEEP_ALIVE_SA_UID_LIST = "KEEP_ALIVE_SA_UID_LIST"; | ||
| 30 | 31 | ||
| 31 | const int32_t INDEX_BUNDLE_NAME = 0; | 32 | const int32_t INDEX_BUNDLE_NAME = 0; |
| 32 | const int32_t INDEX_KEEP_ALIVE_ENABLE = 1; | 33 | const int32_t INDEX_KEEP_ALIVE_ENABLE = 1; |
| 33 | const int32_t INDEX_KEEP_ALIVE_CONFIGURED_LIST = 2; | 34 | const int32_t INDEX_KEEP_ALIVE_CONFIGURED_LIST = 2; |
| 35 | +const int32_t INDEX_KEEP_ALIVE_SA_UID_LIST = 3; | ||
| 34 | } // namespace | 36 | } // namespace |
| 35 | 37 | ||
| 36 | AmsResidentProcessRdbCallBack::AmsResidentProcessRdbCallBack(const AmsRdbConfig &rdbConfig) : rdbConfig_(rdbConfig) {} | 38 | AmsResidentProcessRdbCallBack::AmsResidentProcessRdbCallBack(const AmsRdbConfig &rdbConfig) : rdbConfig_(rdbConfig) {} |
| @@ -41,7 +43,8 @@ int32_t AmsResidentProcessRdbCallBack::OnCreate(NativeRdb::RdbStore &rdbStore) | |||
| 41 | 43 | ||
| 42 | std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + rdbConfig_.tableName + | 44 | std::string createTableSql = "CREATE TABLE IF NOT EXISTS " + rdbConfig_.tableName + |
| 43 | " (KEY_BUNDLE_NAME TEXT NOT NULL PRIMARY KEY," + | 45 | " (KEY_BUNDLE_NAME TEXT NOT NULL PRIMARY KEY," + |
| 44 | - "KEEP_ALIVE_ENABLE TEXT NOT NULL, KEEP_ALIVE_CONFIGURED_LIST TEXT NOT NULL);"; | 46 | + "KEEP_ALIVE_ENABLE TEXT NOT NULL, KEEP_ALIVE_CONFIGURED_LIST TEXT NOT NULL," + |
| 47 | + "KEEP_ALIVE_SA_UID_LIST TEXT NOT NULL);"; | ||
| 45 | auto sqlResult = rdbStore.ExecuteSql(createTableSql); | 48 | auto sqlResult = rdbStore.ExecuteSql(createTableSql); |
| 46 | if (sqlResult != NativeRdb::E_OK) { | 49 | if (sqlResult != NativeRdb::E_OK) { |
| 47 | TAG_LOGE(AAFwkTag::ABILITYMGR, "execute sql error"); | 50 | TAG_LOGE(AAFwkTag::ABILITYMGR, "execute sql error"); |
| @@ -49,7 +52,7 @@ int32_t AmsResidentProcessRdbCallBack::OnCreate(NativeRdb::RdbStore &rdbStore) | |||
| 49 | } | 52 | } |
| 50 | 53 | ||
| 51 | auto &parser = ParserUtil::GetInstance(); | 54 | auto &parser = ParserUtil::GetInstance(); |
| 52 | - std::vector<std::tuple<std::string, std::string, std::string>> initList; | 55 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> initList; |
| 53 | parser.GetResidentProcessRawData(initList); | 56 | parser.GetResidentProcessRawData(initList); |
| 54 | 57 | ||
| 55 | std::vector<NativeRdb::ValuesBucket> valuesBuckets; | 58 | std::vector<NativeRdb::ValuesBucket> valuesBuckets; |
| @@ -58,6 +61,7 @@ int32_t AmsResidentProcessRdbCallBack::OnCreate(NativeRdb::RdbStore &rdbStore) | |||
| 58 | valuesBucket.PutString(KEY_BUNDLE_NAME, std::get<INDEX_BUNDLE_NAME>(item)); | 61 | valuesBucket.PutString(KEY_BUNDLE_NAME, std::get<INDEX_BUNDLE_NAME>(item)); |
| 59 | valuesBucket.PutString(KEY_KEEP_ALIVE_ENABLE, std::get<INDEX_KEEP_ALIVE_ENABLE>(item)); | 62 | valuesBucket.PutString(KEY_KEEP_ALIVE_ENABLE, std::get<INDEX_KEEP_ALIVE_ENABLE>(item)); |
| 60 | valuesBucket.PutString(KEY_KEEP_ALIVE_CONFIGURED_LIST, std::get<INDEX_KEEP_ALIVE_CONFIGURED_LIST>(item)); | 63 | valuesBucket.PutString(KEY_KEEP_ALIVE_CONFIGURED_LIST, std::get<INDEX_KEEP_ALIVE_CONFIGURED_LIST>(item)); |
| 64 | + valuesBucket.PutString(KEY_KEEP_ALIVE_SA_UID_LIST, std::get<INDEX_KEEP_ALIVE_SA_UID_LIST>(item)); | ||
| 61 | 65 | ||
| 62 | valuesBuckets.emplace_back(valuesBucket); | 66 | valuesBuckets.emplace_back(valuesBucket); |
| 63 | } | 67 | } |
| @@ -260,7 +264,7 @@ int32_t AmsResidentProcessRdb::RemoveData(const std::string &bundleName) | |||
| 260 | 264 | ||
| 261 | int32_t AmsResidentProcessRdb::GetResidentProcessRawData(const std::string &bundleName, const std::string &callerName) | 265 | int32_t AmsResidentProcessRdb::GetResidentProcessRawData(const std::string &bundleName, const std::string &callerName) |
| 262 | { | 266 | { |
| 263 | - std::vector<std::tuple<std::string, std::string, std::string>> initList; | 267 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> initList; |
| 264 | ParserUtil::GetInstance().GetResidentProcessRawData(initList); | 268 | ParserUtil::GetInstance().GetResidentProcessRawData(initList); |
| 265 | 269 | ||
| 266 | if (initList.empty() || bundleName.empty() || callerName.empty()) { | 270 | if (initList.empty() || bundleName.empty() || callerName.empty()) { |
| @@ -278,6 +282,7 @@ int32_t AmsResidentProcessRdb::GetResidentProcessRawData(const std::string &bund | |||
| 278 | // we need to update the database | 282 | // we need to update the database |
| 279 | NativeRdb::ValuesBucket valuesBucket; | 283 | NativeRdb::ValuesBucket valuesBucket; |
| 280 | valuesBucket.PutString(KEY_KEEP_ALIVE_CONFIGURED_LIST, configList); | 284 | valuesBucket.PutString(KEY_KEEP_ALIVE_CONFIGURED_LIST, configList); |
| 285 | + valuesBucket.PutString(KEY_KEEP_ALIVE_SA_UID_LIST, std::get<INDEX_KEEP_ALIVE_SA_UID_LIST>(item)); | ||
| 281 | NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME); | 286 | NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME); |
| 282 | absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName); | 287 | absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName); |
| 283 | if (rdbMgr_ != nullptr) { | 288 | if (rdbMgr_ != nullptr) { |
| @@ -291,5 +296,97 @@ int32_t AmsResidentProcessRdb::GetResidentProcessRawData(const std::string &bund | |||
| 291 | 296 | ||
| 292 | return Rdb_Parameter_Err; | 297 | return Rdb_Parameter_Err; |
| 293 | } | 298 | } |
| 299 | + | ||
| 300 | +bool AmsResidentProcessRdb::VerifyUidInJsonArray(const std::string &jsonArrayText, int32_t callerUid) | ||
| 301 | +{ | ||
| 302 | + if (jsonArrayText.empty()) { | ||
| 303 | + return false; | ||
| 304 | + } | ||
| 305 | + auto jsonList = nlohmann::json::parse(jsonArrayText, nullptr, false); | ||
| 306 | + if (jsonList.is_discarded() || !jsonList.is_array()) { | ||
| 307 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "parse sa uid list fail"); | ||
| 308 | + return false; | ||
| 309 | + } | ||
| 310 | + for (const auto &item : jsonList) { | ||
| 311 | + if (item.is_number_integer() && item.get<int64_t>() == static_cast<int64_t>(callerUid)) { | ||
| 312 | + return true; | ||
| 313 | + } | ||
| 314 | + } | ||
| 315 | + return false; | ||
| 316 | +} | ||
| 317 | + | ||
| 318 | +int32_t AmsResidentProcessRdb::VerifySaConfigurationPermissions(const std::string &bundleName, int32_t callerUid) | ||
| 319 | +{ | ||
| 320 | + if (bundleName.empty() || callerUid < 0) { | ||
| 321 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "null bundle name or invalid uid"); | ||
| 322 | + return Rdb_Parameter_Err; | ||
| 323 | + } | ||
| 324 | + | ||
| 325 | + if (rdbMgr_ == nullptr) { | ||
| 326 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "rdb mgr error"); | ||
| 327 | + return Rdb_Parameter_Err; | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME); | ||
| 331 | + absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName); | ||
| 332 | + auto absSharedResultSet = rdbMgr_->QueryData(absRdbPredicates); | ||
| 333 | + if (absSharedResultSet == nullptr) { | ||
| 334 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "null absSharedResultSet"); | ||
| 335 | + return Rdb_Permissions_Err; | ||
| 336 | + } | ||
| 337 | + | ||
| 338 | + ScopeGuard stateGuard([absSharedResultSet] { absSharedResultSet->Close(); }); | ||
| 339 | + auto ret = absSharedResultSet->GoToFirstRow(); | ||
| 340 | + if (ret != NativeRdb::E_OK) { | ||
| 341 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "fail, ret:%{public}d", ret); | ||
| 342 | + return Rdb_Search_Record_Err; | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + std::string saUidList; | ||
| 346 | + ret = absSharedResultSet->GetString(INDEX_KEEP_ALIVE_SA_UID_LIST, saUidList); | ||
| 347 | + if (ret != NativeRdb::E_OK) { | ||
| 348 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "fail, ret: %{public}d", ret); | ||
| 349 | + return Rdb_Search_Record_Err; | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + if (VerifyUidInJsonArray(saUidList, callerUid)) { | ||
| 353 | + return Rdb_OK; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + return Rdb_Permissions_Err; | ||
| 357 | +} | ||
| 358 | + | ||
| 359 | +int32_t AmsResidentProcessRdb::GetSaResidentProcessRawData(const std::string &bundleName, int32_t callerUid) | ||
| 360 | +{ | ||
| 361 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> initList; | ||
| 362 | + ParserUtil::GetInstance().GetResidentProcessRawData(initList); | ||
| 363 | + | ||
| 364 | + if (initList.empty() || bundleName.empty() || callerUid < 0) { | ||
| 365 | + TAG_LOGD(AAFwkTag::ABILITYMGR, "initList size : %{public}d bundleName : %{public}s uid : %{public}d", | ||
| 366 | + static_cast<int>(initList.size()), bundleName.c_str(), callerUid); | ||
| 367 | + return Rdb_Parameter_Err; | ||
| 368 | + } | ||
| 369 | + | ||
| 370 | + for (auto const &item : initList) { | ||
| 371 | + if (std::get<INDEX_BUNDLE_NAME>(item) == bundleName) { | ||
| 372 | + std::string saUidList = std::get<INDEX_KEEP_ALIVE_SA_UID_LIST>(item); | ||
| 373 | + TAG_LOGD(AAFwkTag::ABILITYMGR, "match bundle : %{public}s sa uid list : %{public}s", bundleName.c_str(), | ||
| 374 | + saUidList.c_str()); | ||
| 375 | + NativeRdb::ValuesBucket valuesBucket; | ||
| 376 | + valuesBucket.PutString(KEY_KEEP_ALIVE_CONFIGURED_LIST, std::get<INDEX_KEEP_ALIVE_CONFIGURED_LIST>(item)); | ||
| 377 | + valuesBucket.PutString(KEY_KEEP_ALIVE_SA_UID_LIST, saUidList); | ||
| 378 | + NativeRdb::AbsRdbPredicates absRdbPredicates(ABILITY_RDB_TABLE_NAME); | ||
| 379 | + absRdbPredicates.EqualTo(KEY_BUNDLE_NAME, bundleName); | ||
| 380 | + if (rdbMgr_ != nullptr) { | ||
| 381 | + rdbMgr_->UpdateData(valuesBucket, absRdbPredicates); | ||
| 382 | + } | ||
| 383 | + if (VerifyUidInJsonArray(saUidList, callerUid)) { | ||
| 384 | + return Rdb_OK; | ||
| 385 | + } | ||
| 386 | + } | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + return Rdb_Parameter_Err; | ||
| 390 | +} | ||
| 294 | } // namespace AbilityRuntime | 391 | } // namespace AbilityRuntime |
| 295 | } // namespace OHOS | 392 | } // namespace OHOS |
| @@ -32,6 +32,7 @@ constexpr const char *BUNDLE_NAME = "bundleName"; | |||
| 32 | constexpr const char *KEEP_ALIVE = "keepAlive"; | 32 | constexpr const char *KEEP_ALIVE = "keepAlive"; |
| 33 | constexpr const char *KEEP_ALIVE_ENABLE = "keepAliveEnable"; | 33 | constexpr const char *KEEP_ALIVE_ENABLE = "keepAliveEnable"; |
| 34 | constexpr const char *KEEP_ALIVE_CONFIGURED_LIST = "keepAliveConfiguredList"; | 34 | constexpr const char *KEEP_ALIVE_CONFIGURED_LIST = "keepAliveConfiguredList"; |
| 35 | +constexpr const char *KEEP_ALIVE_SA_UID_LIST = "keepAliveSaUidList"; | ||
| 35 | 36 | ||
| 36 | } // namespace | 37 | } // namespace |
| 37 | ParserUtil &ParserUtil::GetInstance() | 38 | ParserUtil &ParserUtil::GetInstance() |
| @@ -40,7 +41,8 @@ ParserUtil &ParserUtil::GetInstance() | |||
| 40 | return instance; | 41 | return instance; |
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | -void ParserUtil::GetResidentProcessRawData(std::vector<std::tuple<std::string, std::string, std::string>> &list) | 44 | +void ParserUtil::GetResidentProcessRawData( |
| 45 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> &list) | ||
| 44 | { | 46 | { |
| 45 | std::vector<std::string> rootDirList; | 47 | std::vector<std::string> rootDirList; |
| 46 | GetPreInstallRootDirList(rootDirList); | 48 | GetPreInstallRootDirList(rootDirList); |
| @@ -52,8 +54,8 @@ void ParserUtil::GetResidentProcessRawData(std::vector<std::tuple<std::string, s | |||
| 52 | } | 54 | } |
| 53 | } | 55 | } |
| 54 | 56 | ||
| 55 | -void ParserUtil::ParsePreInstallAbilityConfig( | 57 | +void ParserUtil::ParsePreInstallAbilityConfig(const std::string &filePath, |
| 56 | - const std::string &filePath, std::vector<std::tuple<std::string, std::string, std::string>> &list) | 58 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> &list) |
| 57 | { | 59 | { |
| 58 | nlohmann::json jsonBuf; | 60 | nlohmann::json jsonBuf; |
| 59 | if (!ReadFileIntoJson(filePath, jsonBuf)) { | 61 | if (!ReadFileIntoJson(filePath, jsonBuf)) { |
| @@ -67,8 +69,8 @@ void ParserUtil::ParsePreInstallAbilityConfig( | |||
| 67 | FilterInfoFromJson(jsonBuf, list); | 69 | FilterInfoFromJson(jsonBuf, list); |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | -bool ParserUtil::FilterInfoFromJson( | 72 | +bool ParserUtil::FilterInfoFromJson(nlohmann::json &jsonBuf, |
| 71 | - nlohmann::json &jsonBuf, std::vector<std::tuple<std::string, std::string, std::string>> &list) | 73 | + std::vector<std::tuple<std::string, std::string, std::string, std::string>> &list) |
| 72 | { | 74 | { |
| 73 | if (jsonBuf.is_discarded()) { | 75 | if (jsonBuf.is_discarded()) { |
| 74 | TAG_LOGE(AAFwkTag::ABILITYMGR, "format error"); | 76 | TAG_LOGE(AAFwkTag::ABILITYMGR, "format error"); |
| @@ -89,6 +91,7 @@ bool ParserUtil::FilterInfoFromJson( | |||
| 89 | std::string bundleName; | 91 | std::string bundleName; |
| 90 | std::string KeepAliveEnable = "1"; | 92 | std::string KeepAliveEnable = "1"; |
| 91 | std::string KeepAliveConfiguredList; | 93 | std::string KeepAliveConfiguredList; |
| 94 | + std::string KeepAliveSaUidList; | ||
| 92 | for (const auto &array : arrays) { | 95 | for (const auto &array : arrays) { |
| 93 | if (!array.is_object()) { | 96 | if (!array.is_object()) { |
| 94 | continue; | 97 | continue; |
| @@ -116,10 +119,16 @@ bool ParserUtil::FilterInfoFromJson( | |||
| 116 | KeepAliveConfiguredList = array.at(KEEP_ALIVE_CONFIGURED_LIST).dump(); | 119 | KeepAliveConfiguredList = array.at(KEEP_ALIVE_CONFIGURED_LIST).dump(); |
| 117 | } | 120 | } |
| 118 | 121 | ||
| 119 | - list.emplace_back(std::make_tuple(bundleName, KeepAliveEnable, KeepAliveConfiguredList)); | 122 | + if (array.find(KEEP_ALIVE_SA_UID_LIST) != array.end() && array.at(KEEP_ALIVE_SA_UID_LIST).is_array()) { |
| 123 | + // Save directly in the form of an array and parse it when in use | ||
| 124 | + KeepAliveSaUidList = array.at(KEEP_ALIVE_SA_UID_LIST).dump(); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + list.emplace_back(std::make_tuple(bundleName, KeepAliveEnable, KeepAliveConfiguredList, KeepAliveSaUidList)); | ||
| 120 | bundleName.clear(); | 128 | bundleName.clear(); |
| 121 | KeepAliveEnable = "1"; | 129 | KeepAliveEnable = "1"; |
| 122 | KeepAliveConfiguredList.clear(); | 130 | KeepAliveConfiguredList.clear(); |
| 131 | + KeepAliveSaUidList.clear(); | ||
| 123 | } | 132 | } |
| 124 | 133 | ||
| 125 | return true; | 134 | return true; |
| @@ -166,8 +166,35 @@ int32_t ResidentProcessManager::SetResidentProcessEnabled( | |||
| 166 | return ERR_NO_RESIDENT_PERMISSION; | 166 | return ERR_NO_RESIDENT_PERMISSION; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | + return SetResidentProcessEnabledInner(bundleName, updateEnable); | ||
| 170 | +} | ||
| 171 | + | ||
| 172 | +int32_t ResidentProcessManager::SetResidentProcessEnabledForSA( | ||
| 173 | + const std::string &bundleName, int32_t callerUid, bool updateEnable) | ||
| 174 | +{ | ||
| 175 | + TAG_LOGI(AAFwkTag::ABILITYMGR, "SetResidentProcessEnabledForSA,bundle:%{public}s,uid:%{public}d,enable:%{public}d", | ||
| 176 | + bundleName.c_str(), callerUid, updateEnable); | ||
| 177 | + if (bundleName.empty() || callerUid < 0) { | ||
| 178 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "input parameter error"); | ||
| 179 | + return INVALID_PARAMETERS_ERR; | ||
| 180 | + } | ||
| 181 | + auto &rdb = AmsResidentProcessRdb::GetInstance(); | ||
| 182 | + auto rdbResult = rdb.VerifySaConfigurationPermissions(bundleName, callerUid); | ||
| 183 | + auto configResult = rdb.GetSaResidentProcessRawData(bundleName, callerUid); | ||
| 184 | + if (rdbResult != Rdb_OK && configResult != Rdb_OK) { | ||
| 185 | + TAG_LOGE(AAFwkTag::ABILITYMGR, "obtain sa permissions failed. result: %{public}d, configResult: %{public}d", | ||
| 186 | + rdbResult, configResult); | ||
| 187 | + return ERR_NO_RESIDENT_PERMISSION; | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + return SetResidentProcessEnabledInner(bundleName, updateEnable); | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +int32_t ResidentProcessManager::SetResidentProcessEnabledInner(const std::string &bundleName, bool updateEnable) | ||
| 194 | +{ | ||
| 195 | + auto &rdb = AmsResidentProcessRdb::GetInstance(); | ||
| 169 | bool localEnable = false; | 196 | bool localEnable = false; |
| 170 | - rdbResult = rdb.GetResidentProcessEnable(bundleName, localEnable); | 197 | + auto rdbResult = rdb.GetResidentProcessEnable(bundleName, localEnable); |
| 171 | if (rdbResult != Rdb_OK) { | 198 | if (rdbResult != Rdb_OK) { |
| 172 | TAG_LOGE(AAFwkTag::ABILITYMGR, "GetResidentProcess failed:%{public}d", rdbResult); | 199 | TAG_LOGE(AAFwkTag::ABILITYMGR, "GetResidentProcess failed:%{public}d", rdbResult); |
| 173 | return INNER_ERR; | 200 | return INNER_ERR; |
| @@ -40,11 +40,14 @@ bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size) | |||
| 40 | std::string bundleName; | 40 | std::string bundleName; |
| 41 | std::string callerName; | 41 | std::string callerName; |
| 42 | bool updateEnable; | 42 | bool updateEnable; |
| 43 | + int32_t callerUid; | ||
| 43 | FuzzedDataProvider fdp(data, size); | 44 | FuzzedDataProvider fdp(data, size); |
| 44 | bundleName = fdp.ConsumeRandomLengthString(STRING_MAX_LENGTH); | 45 | bundleName = fdp.ConsumeRandomLengthString(STRING_MAX_LENGTH); |
| 45 | callerName = fdp.ConsumeRandomLengthString(STRING_MAX_LENGTH); | 46 | callerName = fdp.ConsumeRandomLengthString(STRING_MAX_LENGTH); |
| 46 | updateEnable = fdp.ConsumeBool(); | 47 | updateEnable = fdp.ConsumeBool(); |
| 48 | + callerUid = fdp.ConsumeIntegral<int32_t>(); | ||
| 47 | residentProcessManager->SetResidentProcessEnabled(bundleName, callerName, updateEnable); | 49 | residentProcessManager->SetResidentProcessEnabled(bundleName, callerName, updateEnable); |
| 50 | + residentProcessManager->SetResidentProcessEnabledForSA(bundleName, callerUid, updateEnable); | ||
| 48 | return true; | 51 | return true; |
| 49 | } | 52 | } |
| 50 | } | 53 | } |
| @@ -1573,6 +1573,46 @@ HWTEST_F(AbilityManagerServiceSecondTest, SetResidentProcessEnable_001, TestSize | |||
| 1573 | ASSERT_NE(abilityMs_, nullptr); | 1573 | ASSERT_NE(abilityMs_, nullptr); |
| 1574 | } | 1574 | } |
| 1575 | 1575 | ||
| 1576 | +/* | ||
| 1577 | + * Feature: AbilityManagerService | ||
| 1578 | + * Function: SetResidentProcessEnabled | ||
| 1579 | + * SubFunction: NA | ||
| 1580 | + * FunctionPoints: AbilityManagerService SetResidentProcessEnabled | ||
| 1581 | + * EnvConditions: NA | ||
| 1582 | + * CaseDescription: Verify SetResidentProcessEnabled with SA caller | ||
| 1583 | + */ | ||
| 1584 | +HWTEST_F(AbilityManagerServiceSecondTest, SetResidentProcessEnable_002, TestSize.Level1) | ||
| 1585 | +{ | ||
| 1586 | + auto abilityMs_ = std::make_shared<AbilityManagerService>(); | ||
| 1587 | + std::string bundleName = "ability.manager.service.test"; | ||
| 1588 | + bool enable = true; | ||
| 1589 | + int oldPerm = MyStatus::GetInstance().permPermission_; | ||
| 1590 | + MyStatus::GetInstance().permPermission_ = 1; // IS_SA_CALL | ||
| 1591 | + // SA call: the sa uid is not in any configured list in ut, so both verify paths fail. | ||
| 1592 | + EXPECT_EQ(abilityMs_->SetResidentProcessEnabled(bundleName, enable), ERR_NO_RESIDENT_PERMISSION); | ||
| 1593 | + MyStatus::GetInstance().permPermission_ = oldPerm; | ||
| 1594 | +} | ||
| 1595 | + | ||
| 1596 | +/* | ||
| 1597 | + * Feature: AbilityManagerService | ||
| 1598 | + * Function: SetResidentProcessEnabled | ||
| 1599 | + * SubFunction: NA | ||
| 1600 | + * FunctionPoints: AbilityManagerService SetResidentProcessEnabled | ||
| 1601 | + * EnvConditions: NA | ||
| 1602 | + * CaseDescription: Verify SetResidentProcessEnabled with non-SA caller | ||
| 1603 | + */ | ||
| 1604 | +HWTEST_F(AbilityManagerServiceSecondTest, SetResidentProcessEnable_003, TestSize.Level1) | ||
| 1605 | +{ | ||
| 1606 | + auto abilityMs_ = std::make_shared<AbilityManagerService>(); | ||
| 1607 | + std::string bundleName = "ability.manager.service.test"; | ||
| 1608 | + bool enable = false; | ||
| 1609 | + int oldPerm = MyStatus::GetInstance().permPermission_; | ||
| 1610 | + MyStatus::GetInstance().permPermission_ = 0; // not SA call | ||
| 1611 | + // Non-SA system app call fails to obtain the caller bundle name in ut. | ||
| 1612 | + EXPECT_EQ(abilityMs_->SetResidentProcessEnabled(bundleName, enable), INNER_ERR); | ||
| 1613 | + MyStatus::GetInstance().permPermission_ = oldPerm; | ||
| 1614 | +} | ||
| 1615 | + | ||
| 1576 | /* | 1616 | /* |
| 1577 | * Feature: AbilityManagerService | 1617 | * Feature: AbilityManagerService |
| 1578 | * Function: DumpMissionInner | 1618 | * Function: DumpMissionInner |
| @@ -147,5 +147,48 @@ HWTEST_F(AbilityResidentProcessRdbTest, RemoveData_002, TestSize.Level1) { | |||
| 147 | int32_t result = amsRdb.RemoveData(emptyBundleName); | 147 | int32_t result = amsRdb.RemoveData(emptyBundleName); |
| 148 | EXPECT_EQ(result, Rdb_Parameter_Err); | 148 | EXPECT_EQ(result, Rdb_Parameter_Err); |
| 149 | } | 149 | } |
| 150 | + | ||
| 151 | +/* | ||
| 152 | + * Feature: AbilityResidentProcessRdb | ||
| 153 | + * Function: VerifySaConfigurationPermissions | ||
| 154 | + * SubFunction: NA | ||
| 155 | + * FunctionPoints: AbilityResidentProcessRdb VerifySaConfigurationPermissions_001 | ||
| 156 | + */ | ||
| 157 | +HWTEST_F(AbilityResidentProcessRdbTest, VerifySaConfigurationPermissions_001, TestSize.Level1) { | ||
| 158 | + EXPECT_EQ(AmsResidentProcessRdb::GetInstance().VerifySaConfigurationPermissions("", 1234), Rdb_Parameter_Err); | ||
| 159 | + EXPECT_EQ(AmsResidentProcessRdb::GetInstance().VerifySaConfigurationPermissions("test.com", -1), | ||
| 160 | + Rdb_Parameter_Err); | ||
| 161 | + // no record for the bundle in the empty table | ||
| 162 | + EXPECT_EQ(AmsResidentProcessRdb::GetInstance().VerifySaConfigurationPermissions( | ||
| 163 | + "com.target.bundle", 1234), Rdb_Search_Record_Err); | ||
| 164 | +} | ||
| 165 | + | ||
| 166 | +/* | ||
| 167 | + * Feature: AbilityResidentProcessRdb | ||
| 168 | + * Function: VerifySaConfigurationPermissions | ||
| 169 | + * SubFunction: NA | ||
| 170 | + * FunctionPoints: AbilityResidentProcessRdb VerifySaConfigurationPermissions_002 | ||
| 171 | + */ | ||
| 172 | +HWTEST_F(AbilityResidentProcessRdbTest, VerifySaConfigurationPermissions_002, TestSize.Level1) { | ||
| 173 | + AmsResidentProcessRdb amsRdb; | ||
| 174 | + std::string bundleName = "test.com"; | ||
| 175 | + int32_t result = amsRdb.VerifySaConfigurationPermissions(bundleName, 1234); | ||
| 176 | + EXPECT_EQ(result, Rdb_Parameter_Err); | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +/* | ||
| 180 | + * Feature: AbilityResidentProcessRdb | ||
| 181 | + * Function: GetSaResidentProcessRawData | ||
| 182 | + * SubFunction: NA | ||
| 183 | + * FunctionPoints: AbilityResidentProcessRdb GetSaResidentProcessRawData_001 | ||
| 184 | + */ | ||
| 185 | +HWTEST_F(AbilityResidentProcessRdbTest, GetSaResidentProcessRawData_001, TestSize.Level1) { | ||
| 186 | + EXPECT_EQ(AmsResidentProcessRdb::GetInstance().GetSaResidentProcessRawData("", 1234), Rdb_Parameter_Err); | ||
| 187 | + EXPECT_EQ(AmsResidentProcessRdb::GetInstance().GetSaResidentProcessRawData("test.com", -1), | ||
| 188 | + Rdb_Parameter_Err); | ||
| 189 | + // the capability config file is absent in ut, so the raw data list is empty | ||
| 190 | + EXPECT_EQ(AmsResidentProcessRdb::GetInstance().GetSaResidentProcessRawData( | ||
| 191 | + "com.target.bundle", 1234), Rdb_Parameter_Err); | ||
| 192 | +} | ||
| 150 | } // namespace AAFwk | 193 | } // namespace AAFwk |
| 151 | } // namespace OHOS | 194 | } // namespace OHOS |
| @@ -48,10 +48,12 @@ public: | |||
| 48 | 48 | ||
| 49 | MOCK_METHOD0(Init, int32_t()); | 49 | MOCK_METHOD0(Init, int32_t()); |
| 50 | MOCK_METHOD2(VerifyConfigurationPermissions, int32_t(const std::string &bundleName, const std::string &callerName)); | 50 | MOCK_METHOD2(VerifyConfigurationPermissions, int32_t(const std::string &bundleName, const std::string &callerName)); |
| 51 | + MOCK_METHOD2(VerifySaConfigurationPermissions, int32_t(const std::string &bundleName, int32_t callerUid)); | ||
| 51 | MOCK_METHOD2(GetResidentProcessEnable, int32_t(const std::string &bundleName, bool &enable)); | 52 | MOCK_METHOD2(GetResidentProcessEnable, int32_t(const std::string &bundleName, bool &enable)); |
| 52 | MOCK_METHOD2(UpdateResidentProcessEnable, int32_t(const std::string &bundleName, bool enable)); | 53 | MOCK_METHOD2(UpdateResidentProcessEnable, int32_t(const std::string &bundleName, bool enable)); |
| 53 | MOCK_METHOD1(RemoveData, int32_t(const std::string &bundleName)); | 54 | MOCK_METHOD1(RemoveData, int32_t(const std::string &bundleName)); |
| 54 | MOCK_METHOD2(GetResidentProcessRawData, int32_t(const std::string &bundleName, const std::string &callerName)); | 55 | MOCK_METHOD2(GetResidentProcessRawData, int32_t(const std::string &bundleName, const std::string &callerName)); |
| 56 | + MOCK_METHOD2(GetSaResidentProcessRawData, int32_t(const std::string &bundleName, int32_t callerUid)); | ||
| 55 | }; | 57 | }; |
| 56 | } // namespace AbilityRuntime | 58 | } // namespace AbilityRuntime |
| 57 | } // namespace OHOS | 59 | } // namespace OHOS |
| @@ -115,6 +115,70 @@ HWTEST_F(ResidentProcessManagerTest, SetResidentProcessEnable_002, TestSize.Leve | |||
| 115 | EXPECT_EQ(manager->SetResidentProcessEnabled(bundleName, callerName, false), ERR_NO_RESIDENT_PERMISSION); | 115 | EXPECT_EQ(manager->SetResidentProcessEnabled(bundleName, callerName, false), ERR_NO_RESIDENT_PERMISSION); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | +/* | ||
| 119 | + * Feature: ResidentProcessManager | ||
| 120 | + * Function: SetResidentProcessEnabledForSA | ||
| 121 | + * SubFunction: NA | ||
| 122 | + * FunctionPoints:ResidentProcessManager SetResidentProcessEnabledForSA | ||
| 123 | + * EnvConditions: NA | ||
| 124 | + * CaseDescription: Verify SetResidentProcessEnabledForSA with invalid input | ||
| 125 | + */ | ||
| 126 | +HWTEST_F(ResidentProcessManagerTest, SetResidentProcessEnableForSA_001, TestSize.Level1) | ||
| 127 | +{ | ||
| 128 | + auto manager = std::make_shared<ResidentProcessManager>(); | ||
| 129 | + ASSERT_NE(manager, nullptr); | ||
| 130 | + std::string bundleName = "com.example.resident.process"; | ||
| 131 | + EXPECT_EQ(manager->SetResidentProcessEnabledForSA("", 1234, false), INVALID_PARAMETERS_ERR); | ||
| 132 | + EXPECT_EQ(manager->SetResidentProcessEnabledForSA(bundleName, -1, false), INVALID_PARAMETERS_ERR); | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +/* | ||
| 136 | + * Feature: ResidentProcessManager | ||
| 137 | + * Function: SetResidentProcessEnabledForSA | ||
| 138 | + * SubFunction: NA | ||
| 139 | + * FunctionPoints:ResidentProcessManager SetResidentProcessEnabledForSA | ||
| 140 | + * EnvConditions: NA | ||
| 141 | + * CaseDescription: Verify SetResidentProcessEnabledForSA rejected when sa uid is not configured | ||
| 142 | + */ | ||
| 143 | +HWTEST_F(ResidentProcessManagerTest, SetResidentProcessEnableForSA_002, TestSize.Level1) | ||
| 144 | +{ | ||
| 145 | + auto manager = std::make_shared<ResidentProcessManager>(); | ||
| 146 | + ASSERT_NE(manager, nullptr); | ||
| 147 | + std::string bundleName = "com.example.resident.process"; | ||
| 148 | + EXPECT_CALL(AmsResidentProcessRdb::GetInstance(), VerifySaConfigurationPermissions(bundleName, 1234)) | ||
| 149 | + .Times(1) | ||
| 150 | + .WillOnce(Return(RdbResult::Rdb_Permissions_Err)); | ||
| 151 | + EXPECT_CALL(AmsResidentProcessRdb::GetInstance(), GetSaResidentProcessRawData(bundleName, 1234)) | ||
| 152 | + .Times(1) | ||
| 153 | + .WillOnce(Return(RdbResult::Rdb_Parameter_Err)); | ||
| 154 | + EXPECT_EQ(manager->SetResidentProcessEnabledForSA(bundleName, 1234, false), ERR_NO_RESIDENT_PERMISSION); | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +/* | ||
| 158 | + * Feature: ResidentProcessManager | ||
| 159 | + * Function: SetResidentProcessEnabledForSA | ||
| 160 | + * SubFunction: NA | ||
| 161 | + * FunctionPoints:ResidentProcessManager SetResidentProcessEnabledForSA | ||
| 162 | + * EnvConditions: NA | ||
| 163 | + * CaseDescription: Verify SetResidentProcessEnabledForSA with sa permission and rdb error | ||
| 164 | + */ | ||
| 165 | +HWTEST_F(ResidentProcessManagerTest, SetResidentProcessEnableForSA_003, TestSize.Level1) | ||
| 166 | +{ | ||
| 167 | + auto manager = std::make_shared<ResidentProcessManager>(); | ||
| 168 | + ASSERT_NE(manager, nullptr); | ||
| 169 | + std::string bundleName = "com.example.resident.process"; | ||
| 170 | + EXPECT_CALL(AmsResidentProcessRdb::GetInstance(), VerifySaConfigurationPermissions(bundleName, 1234)) | ||
| 171 | + .Times(1) | ||
| 172 | + .WillOnce(Return(RdbResult::Rdb_OK)); | ||
| 173 | + EXPECT_CALL(AmsResidentProcessRdb::GetInstance(), GetSaResidentProcessRawData(bundleName, 1234)) | ||
| 174 | + .Times(1) | ||
| 175 | + .WillOnce(Return(RdbResult::Rdb_OK)); | ||
| 176 | + EXPECT_CALL(AmsResidentProcessRdb::GetInstance(), GetResidentProcessEnable(bundleName, _)) | ||
| 177 | + .Times(1) | ||
| 178 | + .WillOnce(Return(RdbResult::Rdb_Parameter_Err)); | ||
| 179 | + EXPECT_EQ(manager->SetResidentProcessEnabledForSA(bundleName, 1234, false), INNER_ERR); | ||
| 180 | +} | ||
| 181 | + | ||
| 118 | /* | 182 | /* |
| 119 | * Feature: ResidentProcessManager | 183 | * Feature: ResidentProcessManager |
| 120 | * Function: PutResidentAbility | 184 | * Function: PutResidentAbility |