diff --git a/services/backup_sa/include/module_ipc/service.h b/services/backup_sa/include/module_ipc/service.h index f281efe3ca6d565dba94a1cb7e0a1ed9984af6fb..e46077d05e2a04da1665ce41e060dc3ab31b6555 100644 --- a/services/backup_sa/include/module_ipc/service.h +++ b/services/backup_sa/include/module_ipc/service.h @@ -32,6 +32,12 @@ #include "thread_pool.h" namespace OHOS::FileManagement::Backup { +struct ExtensionMutexInfo { + std::string bundleName; + std::mutex callbackMutex; + ExtensionMutexInfo(std::string bundleName_) : bundleName(bundleName_) {}; +}; + class Service : public SystemAbility, public ServiceStub, protected NoCopyable { DECLARE_SYSTEM_ABILITY(Service); @@ -273,6 +279,21 @@ public: */ void DelClearBundleRecord(const std::vector &bundleNames); + /** + * @brief 获取extension锁 + * + * @param bundleName 应用名称 + * + */ + std::shared_ptr GetExtensionMutex(const BundleName &bundleName); + + /** + * @brief 清理extension锁 + * + * @param bundleName 应用名称 + * + */ + void RemoveExtensionMutex(const BundleName &bundleName); public: explicit Service(int32_t saID, bool runOnCreate = false) : SystemAbility(saID, runOnCreate) { @@ -484,6 +505,8 @@ private: void HandleCurGroupIncBackupInfos(vector &bundleInfos, std::map> &bundleNameDetailMap, std::map &isClearDataFlags); + + void TimeoutRadarReport(IServiceReverse::Scenario scenario, std::string &bundleName); private: static sptr instance_; static std::mutex instanceLock_; @@ -503,6 +526,9 @@ private: friend class ServiceTest; OHOS::ThreadPool threadPool_; + std::mutex extensionMutexLock_; +public: + std::map> backupExtMutexMap_; }; } // namespace OHOS::FileManagement::Backup diff --git a/services/backup_sa/src/module_ipc/service.cpp b/services/backup_sa/src/module_ipc/service.cpp index 8d59dd80479e6677d8a55e1d37ea8b2b4fc3ff81..576548870d97d626dd7202e55607aad480b39aab 100644 --- a/services/backup_sa/src/module_ipc/service.cpp +++ b/services/backup_sa/src/module_ipc/service.cpp @@ -805,6 +805,12 @@ void Service::NotifyCloneBundleFinish(std::string bundleName, const BackupRestor return; } if (session_->OnBundleFileReady(bundleName)) { + std::shared_ptr mutexPtr = GetExtensionMutex(bundleName); + if (mutexPtr == nullptr) { + HILOGE("extension mutex ptr is nullptr"); + return; + } + std::lock_guard lock(mutexPtr->callbackMutex); auto backUpConnection = session_->GetExtConnection(bundleName); if (backUpConnection == nullptr) { throw BError(BError::Codes::SA_INVAL_ARG, "backUpConnection is empty"); @@ -819,6 +825,7 @@ void Service::NotifyCloneBundleFinish(std::string bundleName, const BackupRestor backUpConnection->DisconnectBackupExtAbility(); ClearSessionAndSchedInfo(bundleName); } + RemoveExtensionMutex(bundleName); SendEndAppGalleryNotify(bundleName); OnAllBundlesFinished(BError(BError::Codes::OK)); } catch (...) { @@ -923,6 +930,12 @@ void Service::ExtConnectDied(const string &callName) HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); try { HILOGI("Begin, bundleName: %{public}s", callName.c_str()); + std::shared_ptr mutexPtr = GetExtensionMutex(callName); + if (mutexPtr == nullptr) { + HILOGE("extension mutex ptr is nullptr"); + return; + } + std::lock_guard lock(mutexPtr->callbackMutex); /* Clear Timer */ session_->StopFwkTimer(callName); session_->StopExtTimer(callName); @@ -942,8 +955,8 @@ void Service::ExtConnectDied(const string &callName) HILOGE("Unexpected exception, bundleName: %{public}s", callName.c_str()); ClearSessionAndSchedInfo(callName); NoticeClientFinish(callName, BError(BError::Codes::EXT_ABILITY_DIED)); - return; } + RemoveExtensionMutex(callName); } void Service::ExtStart(const string &bundleName) @@ -1842,6 +1855,20 @@ std::function Service::TimeOutCallback(wptr ptr, std::string bu }; } +void Service::TimeoutRadarReport(IServiceReverse::Scenario scenario, std::string &bundleName) +{ + int32_t errCode = BError(BError::Codes::EXT_ABILITY_TIMEOUT).GetCode(); + if (scenario == IServiceReverse::Scenario::BACKUP) { + AppRadar::Info info(bundleName, "", "on backup timeout"); + AppRadar::GetInstance().RecordBackupFuncRes(info, "Service::TimeOutCallback", GetUserIdDefault(), + BizStageBackup::BIZ_STAGE_ON_BACKUP, errCode); + } else if (scenario == IServiceReverse::Scenario::RESTORE) { + AppRadar::Info info(bundleName, "", "on restore timeout"); + AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::TimeOutCallback", GetUserIdDefault(), + BizStageRestore::BIZ_STAGE_ON_RESTORE, errCode); + } +} + void Service::DoTimeout(wptr ptr, std::string bundleName) { auto thisPtr = ptr.promote(); @@ -1855,17 +1882,14 @@ void Service::DoTimeout(wptr ptr, std::string bundleName) return; } IServiceReverse::Scenario scenario = sessionPtr->GetScenario(); - int32_t errCode = BError(BError::Codes::EXT_ABILITY_TIMEOUT).GetCode(); - if (scenario == IServiceReverse::Scenario::BACKUP) { - AppRadar::Info info(bundleName, "", "on backup timeout"); - AppRadar::GetInstance().RecordBackupFuncRes(info, "Service::TimeOutCallback", GetUserIdDefault(), - BizStageBackup::BIZ_STAGE_ON_BACKUP, errCode); - } else if (scenario == IServiceReverse::Scenario::RESTORE) { - AppRadar::Info info(bundleName, "", "on restore timeout"); - AppRadar::GetInstance().RecordRestoreFuncRes(info, "Service::TimeOutCallback", GetUserIdDefault(), - BizStageRestore::BIZ_STAGE_ON_RESTORE, errCode); - } + TimeoutRadarReport(scenario, bundleName); try { + std::shared_ptr mutexPtr = GetExtensionMutex(bundleName); + if (mutexPtr == nullptr) { + HILOGE("extension mutex ptr is nullptr"); + return; + } + std::lock_guard lock(mutexPtr->callbackMutex); if (SAUtils::IsSABundleName(bundleName)) { auto sessionConnection = sessionPtr->GetSAExtConnection(bundleName); shared_ptr saConnection = sessionConnection.lock(); @@ -1887,6 +1911,7 @@ void Service::DoTimeout(wptr ptr, std::string bundleName) thisPtr->ClearSessionAndSchedInfo(bundleName); thisPtr->NoticeClientFinish(bundleName, BError(BError::Codes::EXT_ABILITY_TIMEOUT)); } + RemoveExtensionMutex(bundleName); } void Service::AddClearBundleRecord(const std::string &bundleName) diff --git a/services/backup_sa/src/module_ipc/service_incremental.cpp b/services/backup_sa/src/module_ipc/service_incremental.cpp index ae0358d81eea743e994159a7c90d40f162da1a86..1942a5aad460f029ac0b92bc69841ccb5eb44962 100644 --- a/services/backup_sa/src/module_ipc/service_incremental.cpp +++ b/services/backup_sa/src/module_ipc/service_incremental.cpp @@ -85,6 +85,30 @@ ErrCode Service::Release() return BError(BError::Codes::OK); } +std::shared_ptr Service::GetExtensionMutex(const BundleName &bundleName) +{ + std::unique_lock lock(extensionMutexLock_); + auto it = backupExtMutexMap_.find(bundleName); + if (it == backupExtMutexMap_.end()) { + HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str()); + backupExtMutexMap_[bundleName] = std::make_shared(bundleName); + return backupExtMutexMap_[bundleName]; + } + HILOGI("BackupExtMutexMap contain %{public}s", bundleName.c_str()); + return it->second; +} + +void Service::RemoveExtensionMutex(const BundleName &bundleName) +{ + std::unique_lock lock(extensionMutexLock_); + auto it = backupExtMutexMap_.find(bundleName); + if (it == backupExtMutexMap_.end()) { + HILOGI("BackupExtMutexMap not contain %{public}s", bundleName.c_str()); + return; + } + backupExtMutexMap_.erase(it); +} + UniqueFd Service::GetLocalCapabilitiesIncremental(const std::vector &bundleNames) { HITRACE_METER_NAME(HITRACE_TAG_FILEMANAGEMENT, __PRETTY_FUNCTION__); @@ -484,6 +508,12 @@ ErrCode Service::AppIncrementalDone(ErrCode errCode) HILOGI("Service AppIncrementalDone start, callerName is %{public}s, errCode is: %{public}d", callerName.c_str(), errCode); if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) { + std::shared_ptr mutexPtr = GetExtensionMutex(callerName); + if (mutexPtr == nullptr) { + HILOGE("extension mutex ptr is nullptr"); + return BError(BError::Codes::SA_INVAL_ARG, "Extension mutex ptr is null."); + } + std::lock_guard lock(mutexPtr->callbackMutex); auto tempBackUpConnection = session_->GetExtConnection(callerName); auto backUpConnection = tempBackUpConnection.promote(); if (backUpConnection == nullptr) { @@ -500,6 +530,7 @@ ErrCode Service::AppIncrementalDone(ErrCode errCode) ClearSessionAndSchedInfo(callerName); NotifyCallerCurAppIncrementDone(errCode, callerName); } + RemoveExtensionMutex(callerName); OnAllBundlesFinished(BError(BError::Codes::OK)); return BError(BError::Codes::OK); } catch (const BError &e) { diff --git a/services/backup_sa/src/module_ipc/sub_service.cpp b/services/backup_sa/src/module_ipc/sub_service.cpp index b235f14433bbbf08e2083628b0ca9072f78844fa..b3c4cd2591475293fcb4e2302e6f9b0d1a85c55d 100644 --- a/services/backup_sa/src/module_ipc/sub_service.cpp +++ b/services/backup_sa/src/module_ipc/sub_service.cpp @@ -181,6 +181,12 @@ ErrCode Service::AppDone(ErrCode errCode) string callerName = VerifyCallerAndGetCallerName(); HILOGI("Begin, callerName is: %{public}s, errCode: %{public}d", callerName.c_str(), errCode); if (session_->OnBundleFileReady(callerName) || errCode != BError(BError::Codes::OK)) { + std::shared_ptr mutexPtr = GetExtensionMutex(callerName); + if (mutexPtr == nullptr) { + HILOGE("extension mutex ptr is nullptr"); + return BError(BError::Codes::SA_INVAL_ARG); + } + std::lock_guard lock(mutexPtr->callbackMutex); auto backUpConnection = session_->GetExtConnection(callerName); if (backUpConnection == nullptr) { HILOGE("App finish error, backUpConnection is empty"); @@ -197,6 +203,7 @@ ErrCode Service::AppDone(ErrCode errCode) ClearSessionAndSchedInfo(callerName); NotifyCallerCurAppDone(errCode, callerName); } + RemoveExtensionMutex(callerName); OnAllBundlesFinished(BError(BError::Codes::OK)); return BError(BError::Codes::OK); } catch (const BError &e) { diff --git a/services/backup_sa/src/module_ipc/svc_backup_connection.cpp b/services/backup_sa/src/module_ipc/svc_backup_connection.cpp index 53413cc907d7a00e4cd04e6861db36ae5cd73fa4..0492a8e4d928ef93f050da50f96b16eb2848b22c 100644 --- a/services/backup_sa/src/module_ipc/svc_backup_connection.cpp +++ b/services/backup_sa/src/module_ipc/svc_backup_connection.cpp @@ -78,7 +78,6 @@ void SvcBackupConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName { HILOGI("called begin"); isConnected_.store(false); - backupProxy_ = nullptr; string bundleName = element.GetBundleName(); HILOGI("bundleName:%{public}s, OnAbilityDisconnectDone, bundleNameIndexInfo:%{public}s", bundleName.c_str(), bundleNameIndexInfo_.c_str()); diff --git a/tests/mock/module_ipc/service_mock.cpp b/tests/mock/module_ipc/service_mock.cpp index f762791b9e75b80ebea8f280ebb1dc6c9fa982c8..cc295c7f49e3fab7832877e2f74428f315ac2e6e 100644 --- a/tests/mock/module_ipc/service_mock.cpp +++ b/tests/mock/module_ipc/service_mock.cpp @@ -253,4 +253,13 @@ void Service::OnSARestore(const std::string &bundleName, const std::string &resu void Service::ClearResidualBundleData(const std::string &bundleName) { } + +std::shared_ptr Service::GetExtensionMutex(const BundleName &bundleName) +{ + return nullptr; +} + +void Service::RemoveExtensionMutex(const BundleName &bundleName) +{ +} } // namespace OHOS::FileManagement::Backup