• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cinttypes>
18 #include "security_collector_define.h"
19 #include "security_collector_log.h"
20 #include "data_collection.h"
21 
22 namespace OHOS::Security::SecurityCollector {
23 namespace {
24     constexpr int32_t MAX_APP_SUBSCRIBE_COUNT = 100;
25 }
26 
GetInstance()27 SecurityCollectorSubscriberManager &SecurityCollectorSubscriberManager::GetInstance()
28 {
29     static SecurityCollectorSubscriberManager instance;
30     return instance;
31 }
32 
GetExtraInfo()33 std::string SecurityCollectorSubscriberManager::CollectorListenner::GetExtraInfo()
34 {
35     if (subscriber_) {
36         return subscriber_->GetSecurityCollectorSubscribeInfo().GetEvent().extra;
37     }
38     return {};
39 }
40 
GetEventId()41 int64_t SecurityCollectorSubscriberManager::CollectorListenner::GetEventId()
42 {
43     if (subscriber_) {
44         return subscriber_->GetSecurityCollectorSubscribeInfo().GetEvent().eventId;
45     }
46     return {};
47 }
48 
OnNotify(const Event & event)49 void SecurityCollectorSubscriberManager::CollectorListenner::OnNotify(const Event &event)
50 {
51     SecurityCollectorSubscriberManager::GetInstance().NotifySubscriber(event);
52 }
53 
NotifySubscriber(const Event & event)54 void SecurityCollectorSubscriberManager::NotifySubscriber(const Event &event)
55 {
56     std::lock_guard<std::mutex> lock(collectorMutex_);
57     LOGD("publish event: eventid:%{public}" PRId64 ", version:%{public}s, extra:%{public}s",
58         event.eventId, event.version.c_str(), event.extra.c_str());
59     for (auto iter : event.eventSubscribes) {
60         LOGD("publish event: subscribe:%{public}s", iter.c_str());
61     }
62     const auto it = eventToSubscribers_.find(event.eventId);
63     if (it == eventToSubscribers_.end()) {
64         return;
65     }
66     for (const auto &subscriber : it->second) {
67         if (subscriber != nullptr) {
68             subscriber->OnChange(event);
69         }
70     }
71 }
72 
GetAppSubscribeCount(const std::string & appName)73 int32_t SecurityCollectorSubscriberManager::GetAppSubscribeCount(const std::string &appName)
74 {
75     int32_t count = 0;
76     for (const auto &element : eventToSubscribers_) {
77         const auto &subscribers = element.second;
78         count = std::count_if(subscribers.begin(), subscribers.end(), [appName] (const auto &subscriber) {
79             return subscriber->GetAppName() == appName;
80         });
81     }
82     LOGI("subcirbipt count, appName=%{public}s, count=%{public}d", appName.c_str(), count);
83     return count;
84 }
85 
GetAppSubscribeCount(const std::string & appName,int64_t eventId)86 int32_t SecurityCollectorSubscriberManager::GetAppSubscribeCount(const std::string &appName, int64_t eventId)
87 {
88     const auto &subscribers = eventToSubscribers_[eventId];
89     if (std::any_of(subscribers.begin(), subscribers.end(), [appName] (const auto &subscriber) {
90             return subscriber->GetAppName() == appName;
91         })) {
92         LOGI("subcirbipt count 1, appName=%{public}s, eventId:%{public}" PRId64, appName.c_str(), eventId);
93         return 1;
94     }
95     LOGI("subcirbipt count 0, appName=%{public}s, eventId:%{public}" PRId64, appName.c_str(), eventId);
96     return 0;
97 }
98 
FindEventIds(const sptr<IRemoteObject> & remote)99 std::set<int64_t> SecurityCollectorSubscriberManager::FindEventIds(const sptr<IRemoteObject> &remote)
100 {
101     std::set<int64_t> eventIds;
102     for (const auto &element : eventToSubscribers_) {
103         const auto &subscribers = element.second;
104         auto it = std::find_if(subscribers.begin(), subscribers.end(),
105             [remote] (const auto &subscriber) { return subscriber->GetRemote() == remote; });
106         if (it != subscribers.end()) {
107             LOGI("Find Event By Callback appName=%{public}s, eventId:%{public}" PRId64,
108                  (*it)->GetAppName().c_str(), element.first);
109             eventIds.emplace(element.first);
110         }
111     }
112     return eventIds;
113 }
114 
FindSecurityCollectorSubscribers(const sptr<IRemoteObject> & remote)115 auto SecurityCollectorSubscriberManager::FindSecurityCollectorSubscribers(const sptr<IRemoteObject> &remote)
116 {
117     std::set<std::shared_ptr<SecurityCollectorSubscriber>> subscribers;
118     for (const auto &element : eventToSubscribers_) {
119         auto it = std::find_if(element.second.begin(), element.second.end(),
120             [remote] (const auto &d) { return d->GetRemote() == remote; });
121         if (it != element.second.end()) {
122             LOGI("Find Event Listenner appName=%{public}s, eventId:%{public}" PRId64,
123                 (*it)->GetAppName().c_str(), element.first);
124             subscribers.emplace(*it);
125         }
126     }
127     return subscribers;
128 }
SubscribeCollector(const std::shared_ptr<SecurityCollectorSubscriber> & subscriber)129 bool SecurityCollectorSubscriberManager::SubscribeCollector(
130     const std::shared_ptr<SecurityCollectorSubscriber> &subscriber)
131 {
132     std::lock_guard<std::mutex> lock(collectorMutex_);
133     if (subscriber == nullptr) {
134         LOGE("subscriber is null");
135         return false;
136     }
137     std::string appName = subscriber->GetAppName();
138     int64_t eventId = subscriber->GetSecurityCollectorSubscribeInfo().GetEvent().eventId;
139     LOGI("appName:%{public}s, eventId:%{public}" PRId64, appName.c_str(), eventId);
140     if (GetAppSubscribeCount(appName) >= MAX_APP_SUBSCRIBE_COUNT) {
141         LOGE("Max count for app name:%{public}s", appName.c_str());
142         return false;
143     }
144     if (GetAppSubscribeCount(appName, eventId) > 0) {
145         LOGE("Already subscribed eventId:%{public}" PRId64, eventId);
146         return false;
147     }
148     if (collectorListenner_ == nullptr) {
149         collectorListenner_ = std::make_shared<SecurityCollectorSubscriberManager::CollectorListenner>(nullptr);
150     }
151     LOGI("Scheduling start collector, eventId:%{public}" PRId64, eventId);
152     if (!DataCollection::GetInstance().StartCollectors(std::vector<int64_t>{eventId}, collectorListenner_)) {
153         LOGE("failed to start collectors");
154         return false;
155     }
156     eventToSubscribers_[eventId].emplace(subscriber);
157     LOGI("eventId:%{public} " PRId64 ", callbackCount:%{public}zu", eventId, eventToSubscribers_[eventId].size());
158     int64_t duration = subscriber->GetSecurityCollectorSubscribeInfo().GetDuration();
159     if (duration > 0) {
160         auto remote = subscriber->GetRemote();
161         auto timer = std::make_shared<CleanupTimer>();
162         timers_.emplace(remote, timer);
163         timer->Start(remote, duration);
164     }
165     return true;
166 }
167 
UnsubscribeCollector(const sptr<IRemoteObject> & remote)168 bool SecurityCollectorSubscriberManager::UnsubscribeCollector(const sptr<IRemoteObject> &remote)
169 {
170     std::lock_guard<std::mutex> lock(collectorMutex_);
171     std::set<int64_t> eventIds = FindEventIds(remote);
172     for (int64_t eventId : eventIds) {
173         LOGI("Remove collecctor, eventId:%{public}" PRId64, eventId);
174         if (eventId == -1) {
175             LOGE("eventId is not found");
176             return false;
177         }
178         auto subscribers = FindSecurityCollectorSubscribers(remote);
179         if (subscribers.size() == 0) {
180             LOGE("subscriber is null");
181             return false;
182         }
183         for (auto subscriber: subscribers) {
184             eventToSubscribers_[eventId].erase(subscriber);
185             if (eventToSubscribers_[eventId].size() == 0) {
186                 LOGI("Scheduling stop collector, eventId:%{public}" PRId64, eventId);
187                 if (!DataCollection::GetInstance().StopCollectors(std::vector<int64_t>{eventId})) {
188                     LOGE("failed to stop collectors");
189                 }
190                 eventToSubscribers_.erase(eventId);
191             }
192         }
193     }
194 
195     LOGI("erase timer befoe remoteObject");
196     timers_.erase(remote);
197     LOGI("erase timer after remoteObject");
198     return true;
199 }
200 }