diff --git a/services/core/include/pasteboard_service.h b/services/core/include/pasteboard_service.h index 787ee38d65daf2534fade127eb26fb6dfd5d8420..7b2d70c0bec8c66b1794530267eadcb5b989dffe 100644 --- a/services/core/include/pasteboard_service.h +++ b/services/core/include/pasteboard_service.h @@ -205,7 +205,10 @@ private: return l->AsObject() < r->AsObject(); } }; - using ObserverMap = std::map, classcomp>>>; + using ObserverMap = std::map, + std::shared_ptr, classcomp>>>; + uint32_t GetObserversSize(int32_t userId, pid_t pid, ObserverMap &observerMap); + uint32_t GetAllObserversSize(int32_t userId, pid_t pid); void AddSysAbilityListener(); int32_t Init(); void InitScreenStatus(); @@ -362,10 +365,12 @@ private: pid_t pid_; }; int32_t AppExit(pid_t pid); + void RemoveObserverByPid(int32_t userId, pid_t pid, ObserverMap &observerMap); ConcurrentMap> clients_; static constexpr pid_t INVALID_UID = -1; static constexpr pid_t INVALID_PID = -1; static constexpr uint32_t INVALID_TOKEN = 0; + static constexpr uint32_t MAX_OBSERVER_COUNT = 10; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/core/src/pasteboard_service.cpp b/services/core/src/pasteboard_service.cpp index 39568cbcd3de2fc2c684cd01efb2a66ce4925efc..af95e87bed596cc9f159bbf020536ea361835977 100644 --- a/services/core/src/pasteboard_service.cpp +++ b/services/core/src/pasteboard_service.cpp @@ -1661,6 +1661,24 @@ void PasteboardService::UnsubscribeAllObserver(PasteboardObserverType type) } } +uint32_t PasteboardService::GetAllObserversSize(int32_t userId, pid_t pid) +{ + auto localObserverSize = GetObserversSize(userId, pid, observerLocalChangedMap_); + auto remoteObserverSize = GetObserversSize(userId, pid, observerRemoteChangedMap_); + auto eventObserverSize = GetObserversSize(COMMON_USERID, pid, observerEventMap_); + return localObserverSize + remoteObserverSize + eventObserverSize; +} + +uint32_t PasteboardService::GetObserversSize(int32_t userId, pid_t pid, ObserverMap &observerMap) +{ + auto countKey = std::make_pair(userId, pid); + auto it = observerMap.find(countKey); + if (it != observerMap.end()) { + return it->second->size(); + } + return 0; +} + void PasteboardService::AddObserver(int32_t userId, const sptr &observer, ObserverMap &observerMap) { @@ -1669,35 +1687,45 @@ void PasteboardService::AddObserver(int32_t userId, const sptr lock(observerMutex_); - auto it = observerMap.find(userId); + auto callPid = IPCSkeleton::GetCallingPid(); + auto callObserverKey = std::make_pair(userId, callPid); + auto it = observerMap.find(callObserverKey); std::shared_ptr, classcomp>> observers; if (it != observerMap.end()) { observers = it->second; } else { observers = std::make_shared, classcomp>>(); - observerMap.insert(std::make_pair(userId, observers)); + observerMap.insert(std::make_pair(callObserverKey, observers)); + } + auto allObserverCount = GetAllObserversSize(userId, callPid); + if (allObserverCount >= MAX_OBSERVER_COUNT) { + PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer count over limit. callPid:%{public}d", callPid); + return; } observers->insert(observer); RADAR_REPORT(DFX_OBSERVER, DFX_ADD_OBSERVER, DFX_SUCCESS); - PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "observers->size = %{public}u.", - static_cast(observers->size())); + PASTEBOARD_HILOGI( + PASTEBOARD_MODULE_SERVICE, "observers->size = %{public}u.", static_cast(observers->size())); } -void PasteboardService::RemoveSingleObserver(int32_t userId, const sptr &observer, - ObserverMap &observerMap) +void PasteboardService::RemoveSingleObserver( + int32_t userId, const sptr &observer, ObserverMap &observerMap) { if (observer == nullptr) { PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null."); return; } std::lock_guard lock(observerMutex_); - auto it = observerMap.find(userId); + auto callPid = IPCSkeleton::GetCallingPid(); + auto callObserverKey = std::make_pair(userId, callPid); + auto it = observerMap.find(callObserverKey); if (it == observerMap.end()) { + PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "user id not found userId is %{public}d", userId); return; } auto observers = it->second; - PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers size: %{public}u.", - static_cast(observers->size())); + PASTEBOARD_HILOGD( + PASTEBOARD_MODULE_SERVICE, "observers size: %{public}u.", static_cast(observers->size())); auto eraseNum = observers->erase(observer); RADAR_REPORT(DFX_OBSERVER, DFX_REMOVE_SINGLE_OBSERVER, DFX_SUCCESS); PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers size = %{public}u, eraseNum = %{public}zu", @@ -1707,18 +1735,14 @@ void PasteboardService::RemoveSingleObserver(int32_t userId, const sptr lock(observerMutex_); - auto it = observerMap.find(userId); - if (it == observerMap.end()) { - PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "observer empty."); - return; + for (auto it = observerMap.begin(); it != observerMap.end();) { + if (it->first.first == userId) { + it = observerMap.erase(it); + } else { + ++it; + } } - auto observers = it->second; - PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers size: %{public}u.", - static_cast(observers->size())); - auto eraseNum = observerMap.erase(userId); RADAR_REPORT(DFX_OBSERVER, DFX_REMOVE_ALL_OBSERVER, DFX_SUCCESS); - PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers size = %{public}u, eraseNum = %{public}zu", - static_cast(observers->size()), eraseNum); } int32_t PasteboardService::SetGlobalShareOption(const std::map &globalShareOptions) @@ -2476,9 +2500,24 @@ void PasteboardService::CommonEventSubscriber() EventFwk::CommonEventManager::SubscribeCommonEvent(commonEventSubscriber_); } +void PasteboardService::RemoveObserverByPid(int32_t userId, pid_t pid, ObserverMap &observerMap) +{ + std::lock_guard lock(observerMutex_); + auto callObserverKey = std::make_pair(userId, pid); + auto it = observerMap.find(callObserverKey); + if (it == observerMap.end()) { + return; + } + observerMap.erase(callObserverKey); +} + int32_t PasteboardService::AppExit(pid_t pid) { PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "pid %{public}d exit.", pid); + int32_t userId = GetCurrentAccountId(); + RemoveObserverByPid(userId, pid, observerLocalChangedMap_); + RemoveObserverByPid(userId, pid, observerRemoteChangedMap_); + RemoveObserverByPid(COMMON_USERID, pid, observerEventMap_); std::vector networkIds; p2pMap_.EraseIf([pid, &networkIds, this](auto &networkId, auto &pidMap) { pidMap.EraseIf([pid, this](auto &key, auto &value) {