已开启
常驻应用按需拉起支持SA #20370
常驻应用按需拉起支持SA #20370
已开启
zhangtao创建于 4 天前
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);
157private:174private:
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 {
26class ParserUtil final {26class ParserUtil final {
27public:27public:
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 
31private:32private:
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 AbilityRuntime40} // namespace AbilityRuntime
40} // namespace OHOS41} // 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();
98private:108private:
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
16173int32_t AbilityManagerService::SetResidentProcessEnabled(const std::string &bundleName, bool enable)16173int32_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";
27const std::string KEY_BUNDLE_NAME = "KEY_BUNDLE_NAME";27const std::string KEY_BUNDLE_NAME = "KEY_BUNDLE_NAME";
28const std::string KEY_KEEP_ALIVE_ENABLE = "KEEP_ALIVE_ENABLE";28const std::string KEY_KEEP_ALIVE_ENABLE = "KEEP_ALIVE_ENABLE";
29const std::string KEY_KEEP_ALIVE_CONFIGURED_LIST = "KEEP_ALIVE_CONFIGURED_LIST";29const 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 
31const int32_t INDEX_BUNDLE_NAME = 0;32const int32_t INDEX_BUNDLE_NAME = 0;
32const int32_t INDEX_KEEP_ALIVE_ENABLE = 1;33const int32_t INDEX_KEEP_ALIVE_ENABLE = 1;
33const int32_t INDEX_KEEP_ALIVE_CONFIGURED_LIST = 2;34const int32_t INDEX_KEEP_ALIVE_CONFIGURED_LIST = 2;
35+const int32_t INDEX_KEEP_ALIVE_SA_UID_LIST = 3;
34} // namespace36} // namespace
35 37 
36AmsResidentProcessRdbCallBack::AmsResidentProcessRdbCallBack(const AmsRdbConfig &rdbConfig) : rdbConfig_(rdbConfig) {}38AmsResidentProcessRdbCallBack::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 
261int32_t AmsResidentProcessRdb::GetResidentProcessRawData(const std::string &bundleName, const std::string &callerName)265int32_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 database282 // 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 AbilityRuntime391} // namespace AbilityRuntime
295} // namespace OHOS392} // namespace OHOS
@@ -32,6 +32,7 @@ constexpr const char *BUNDLE_NAME = "bundleName";
32constexpr const char *KEEP_ALIVE = "keepAlive";32constexpr const char *KEEP_ALIVE = "keepAlive";
33constexpr const char *KEEP_ALIVE_ENABLE = "keepAliveEnable";33constexpr const char *KEEP_ALIVE_ENABLE = "keepAliveEnable";
34constexpr const char *KEEP_ALIVE_CONFIGURED_LIST = "keepAliveConfiguredList";34constexpr const char *KEEP_ALIVE_CONFIGURED_LIST = "keepAliveConfiguredList";
35+constexpr const char *KEEP_ALIVE_SA_UID_LIST = "keepAliveSaUidList";
35 36 
36} // namespace37} // namespace
37ParserUtil &ParserUtil::GetInstance()38ParserUtil &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: AbilityManagerService1617 * Feature: AbilityManagerService
1578 * Function: DumpMissionInner1618 * 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 AAFwk193} // namespace AAFwk
151} // namespace OHOS194} // 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 AbilityRuntime58} // namespace AbilityRuntime
57} // namespace OHOS59} // 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: ResidentProcessManager183 * Feature: ResidentProcessManager
120 * Function: PutResidentAbility184 * Function: PutResidentAbility