1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "security_collector_subscriber_manager.h"
17 #include "security_collector_define.h"
18 #include "security_collector_log.h"
19 #include "data_collection.h"
20
21 namespace OHOS::Security::SecurityCollector {
22 namespace {
23 constexpr int32_t MAX_APP_SUBSCRIBE_COUNT = 100;
24 }
SecurityCollectorSubscriberManager()25 SecurityCollectorSubscriberManager::SecurityCollectorSubscriberManager()
26 {
27 }
28
GetExtraInfo()29 std::string SecurityCollectorSubscriberManager::CollectorListenner::GetExtraInfo()
30 {
31 if (subscriber_) {
32 return subscriber_->GetSecurityCollectorSubscribeInfo().GetEvent().extra;
33 }
34 return {};
35 }
36
OnNotify(const Event & event)37 void SecurityCollectorSubscriberManager::CollectorListenner::OnNotify(const Event &event)
38 {
39 SecurityCollectorSubscriberManager::GetInstance().NotifySubscriber(event);
40 }
41
NotifySubscriber(const Event & event)42 void SecurityCollectorSubscriberManager::NotifySubscriber(const Event &event)
43 {
44 std::lock_guard<std::mutex> lock(collectorMutex_);
45 LOGE("publish event: eventid:%{public}" PRId64 ", version:%{public}s, extra:%{public}s",
46 event.eventId, event.version.c_str(), event.extra.c_str());
47 const auto it = eventToSubscribers_.find(event.eventId);
48 if (it == eventToSubscribers_.end()) {
49 return;
50 }
51 for (const auto &subscriber : it->second) {
52 if (subscriber != nullptr) {
53 subscriber->OnChange(event);
54 }
55 }
56 }
57
GetAppSubscribeCount(const std::string & appName)58 int32_t SecurityCollectorSubscriberManager::GetAppSubscribeCount(const std::string &appName)
59 {
60 int32_t count = 0;
61 for (const auto &element : eventToSubscribers_) {
62 const auto &subscribers = element.second;
63 count = std::count_if(subscribers.begin(), subscribers.end(), [appName] (const auto &subscriber) {
64 return subscriber->GetAppName() == appName;
65 });
66 }
67 LOGI("subcirbipt count, appName=%{public}s, count=%{public}d", appName.c_str(), count);
68 return count;
69 }
70
GetAppSubscribeCount(const std::string & appName,int64_t eventId)71 int32_t SecurityCollectorSubscriberManager::GetAppSubscribeCount(const std::string &appName, int64_t eventId)
72 {
73 const auto &subscribers = eventToSubscribers_[eventId];
74 if (std::any_of(subscribers.begin(), subscribers.end(), [appName] (const auto &subscriber) {
75 return subscriber->GetAppName() == appName;
76 })) {
77 LOGI("subcirbipt count 1, appName=%{public}s, eventId:%{public}" PRId64 "", appName.c_str(), eventId);
78 return 1;
79 }
80 LOGI("subcirbipt count 0, appName=%{public}s, eventId:%{public}" PRId64 "", appName.c_str(), eventId);
81 return 0;
82 }
83
FindEventIds(const sptr<IRemoteObject> & remote)84 std::set<int64_t> SecurityCollectorSubscriberManager::FindEventIds(const sptr<IRemoteObject> &remote)
85 {
86 std::set<int64_t> eventIds;
87 for (const auto &element : eventToSubscribers_) {
88 const auto &subscribers = element.second;
89 auto it = std::find_if(subscribers.begin(), subscribers.end(),
90 [remote] (const auto &subscriber) { return subscriber->GetRemote() == remote; });
91 if (it != subscribers.end()) {
92 LOGI("Find Event By Callback appName=%{public}s, eventId:%{public}" PRId64 "",
93 (*it)->GetAppName().c_str(), element.first);
94 eventIds.emplace(element.first);
95 }
96 }
97 return eventIds;
98 }
99
FindSecurityCollectorSubscribers(const sptr<IRemoteObject> & remote)100 auto SecurityCollectorSubscriberManager::FindSecurityCollectorSubscribers(const sptr<IRemoteObject> &remote)
101 {
102 std::set<std::shared_ptr<SecurityCollectorSubscriber>> subscribers;
103 for (const auto &element : eventToSubscribers_) {
104 auto it = std::find_if(element.second.begin(), element.second.end(),
105 [remote] (const auto &d) { return d->GetRemote() == remote; });
106 if (it != element.second.end()) {
107 LOGI("Find Event Listenner appName=%{public}s, eventId:%{public}" PRId64 "",
108 (*it)->GetAppName().c_str(), element.first);
109 subscribers.emplace(*it);
110 }
111 }
112 return subscribers;
113 }
SubscribeCollector(const std::shared_ptr<SecurityCollectorSubscriber> & subscriber)114 bool SecurityCollectorSubscriberManager::SubscribeCollector(
115 const std::shared_ptr<SecurityCollectorSubscriber> &subscriber)
116 {
117 std::lock_guard<std::mutex> lock(collectorMutex_);
118 if (subscriber == nullptr) {
119 LOGE("subscriber is null");
120 return false;
121 }
122 std::string appName = subscriber->GetAppName();
123 int64_t eventId = subscriber->GetSecurityCollectorSubscribeInfo().GetEvent().eventId;
124 LOGI("appName:%{public}s, eventId:%{public}" PRId64 "", appName.c_str(), eventId);
125 if (GetAppSubscribeCount(appName) >= MAX_APP_SUBSCRIBE_COUNT) {
126 LOGE("Max count for app name:%{public}s", appName.c_str());
127 return false;
128 }
129 if (GetAppSubscribeCount(appName, eventId) > 0) {
130 LOGE("Already subscribed eventId:%{public}" PRId64 "", eventId);
131 return false;
132 }
133 if (eventToListenner_.count(eventId) == 0) {
134 auto collectorListenner = std::make_shared<SecurityCollectorSubscriberManager::CollectorListenner>(subscriber);
135 LOGI("Scheduling start collector, eventId:%{public}" PRId64 "", eventId);
136 if (!DataCollection::GetInstance().StartCollectors(std::vector<int64_t>{eventId}, collectorListenner)) {
137 LOGE("failed to start collectors");
138 return false;
139 }
140 eventToListenner_.emplace(eventId, collectorListenner);
141 } else {
142 LOGI("Scheduling do not start collecctor, eventId:%{public}" PRId64 "", eventId);
143 }
144 eventToSubscribers_[eventId].emplace(subscriber);
145 LOGI("eventId:%{public}" PRId64 ", callbackCount:%{public}u",
146 eventId, static_cast<uint32_t>(eventToSubscribers_[eventId].size()));
147 int64_t duration = subscriber->GetSecurityCollectorSubscribeInfo().GetDuration();
148 if (duration > 0) {
149 auto remote = subscriber->GetRemote();
150 auto timer = std::make_shared<CleanupTimer>();
151 timers_.emplace(remote, timer);
152 timer->Start(remote, duration);
153 }
154 return true;
155 }
156
UnsubscribeCollector(const sptr<IRemoteObject> & remote)157 bool SecurityCollectorSubscriberManager::UnsubscribeCollector(const sptr<IRemoteObject> &remote)
158 {
159 std::lock_guard<std::mutex> lock(collectorMutex_);
160 std::set<int64_t> eventIds = FindEventIds(remote);
161 for (int64_t eventId : eventIds) {
162 LOGI("Remove collecctor, eventId:%{public}" PRId64 "", eventId);
163 if (eventId == -1) {
164 LOGE("eventId is not found");
165 return false;
166 }
167 auto subscribers = FindSecurityCollectorSubscribers(remote);
168 if (subscribers.size() == 0) {
169 LOGE("subscriber is null");
170 return false;
171 }
172 for (auto subscriber: subscribers) {
173 eventToSubscribers_[eventId].erase(subscriber);
174 if (eventToSubscribers_[eventId].size() == 0) {
175 LOGI("Scheduling stop collector, eventId:%{public}" PRId64 "", eventId);
176 (void) DataCollection::GetInstance().StopCollectors(std::vector<int64_t>{eventId});
177 eventToSubscribers_.erase(eventId);
178 eventToListenner_.erase(eventId);
179 }
180 }
181 }
182
183 LOGI("erase timer befoe remoteObject");
184 timers_.erase(remote);
185 LOGI("erase timer after remoteObject");
186 return true;
187 }
188 }