1 /*
2 * Copyright (c) 2022-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 "device_status_collect_manager.h"
17
18 #include "datetime_ex.h"
19 #include "device_timed_collect.h"
20 #ifdef SUPPORT_DEVICE_MANAGER
21 #include "device_networking_collect.h"
22 #endif
23 #ifdef SUPPORT_COMMON_EVENT
24 #include "common_event_collect.h"
25 #endif
26 #ifdef SUPPORT_SWITCH_COLLECT
27 #include "device_switch_collect.h"
28 #endif
29 #include "device_param_collect.h"
30 #include "memory_guard.h"
31 #include "sam_log.h"
32 #include "system_ability_manager.h"
33
34 namespace OHOS {
35 namespace {
36 constexpr int32_t TO_MILLISECOND = 1000;
37 }
Init(const std::list<SaProfile> & saProfiles)38 void DeviceStatusCollectManager::Init(const std::list<SaProfile>& saProfiles)
39 {
40 HILOGI("DeviceStatusCollectManager Init begin");
41 FilterOnDemandSaProfiles(saProfiles);
42 collectHandler_ = std::make_shared<FFRTHandler>("collect");
43 sptr<ICollectPlugin> deviceParamCollect = new DeviceParamCollect(this);
44 deviceParamCollect->Init(saProfiles);
45 collectPluginMap_[PARAM] = deviceParamCollect;
46 #ifdef SUPPORT_DEVICE_MANAGER
47 sptr<ICollectPlugin> networkingCollect = new DeviceNetworkingCollect(this);
48 collectPluginMap_[DEVICE_ONLINE] = networkingCollect;
49 #endif
50 #ifdef SUPPORT_COMMON_EVENT
51 sptr<ICollectPlugin> eventStatuscollect = new CommonEventCollect(this);
52 eventStatuscollect->Init(onDemandSaProfiles_);
53 collectPluginMap_[COMMON_EVENT] = eventStatuscollect;
54 #endif
55 #ifdef SUPPORT_SWITCH_COLLECT
56 sptr<ICollectPlugin> deviceSwitchCollect = new DeviceSwitchCollect(this);
57 deviceSwitchCollect->Init(saProfiles);
58 collectPluginMap_[SETTING_SWITCH] = deviceSwitchCollect;
59 #endif
60 sptr<ICollectPlugin> timedCollect = new DeviceTimedCollect(this);
61 timedCollect->Init(onDemandSaProfiles_);
62 collectPluginMap_[TIMED_EVENT] = timedCollect;
63 StartCollect();
64 HILOGI("DeviceStatusCollectManager Init end");
65 }
66
FilterOnDemandSaProfiles(const std::list<SaProfile> & saProfiles)67 void DeviceStatusCollectManager::FilterOnDemandSaProfiles(const std::list<SaProfile>& saProfiles)
68 {
69 std::unique_lock<std::shared_mutex> writeLock(saProfilesLock_);
70 for (auto& saProfile : saProfiles) {
71 if (saProfile.startOnDemand.onDemandEvents.empty() && saProfile.stopOnDemand.onDemandEvents.empty()) {
72 continue;
73 }
74 onDemandSaProfiles_.emplace_back(saProfile);
75 }
76 }
77
GetSaControlListByPersistEvent(const OnDemandEvent & event,std::list<SaControlInfo> & saControlList)78 void DeviceStatusCollectManager::GetSaControlListByPersistEvent(const OnDemandEvent& event,
79 std::list<SaControlInfo>& saControlList)
80 {
81 #ifdef PREFERENCES_ENABLE
82 std::shared_ptr<PreferencesUtil> preferencesUtil = PreferencesUtil::GetInstance();
83 if (preferencesUtil == nullptr) {
84 HILOGW("GetSaControlListByPersistEvent preferencesUtil is nullptr");
85 return;
86 }
87 std::string value = preferencesUtil->ObtainString(event.ToString(), std::string());
88 if (value == std::string()) {
89 return;
90 }
91 std::vector<std::string> strVector;
92 SplitStr(value, "+", strVector);
93 size_t vectorSize = strVector.size();
94 for (size_t i = 0; i < vectorSize; i++) {
95 OnDemandPolicyType type;
96 int32_t systemAbilityId = -1;
97 HILOGD("vector is : %{public}s", strVector[i].c_str());
98 StringToTypeAndSaid(strVector[i], type, systemAbilityId);
99 SaControlInfo control;
100 if (type == OnDemandPolicyType::START_POLICY) {
101 control = {START_ON_DEMAND, systemAbilityId };
102 } else {
103 control = {STOP_ON_DEMAND, systemAbilityId };
104 }
105 saControlList.emplace_back(control);
106 }
107 #endif
108 }
109
GetSaControlListByEvent(const OnDemandEvent & event,std::list<SaControlInfo> & saControlList)110 void DeviceStatusCollectManager::GetSaControlListByEvent(const OnDemandEvent& event,
111 std::list<SaControlInfo>& saControlList)
112 {
113 std::shared_lock<std::shared_mutex> readLock(saProfilesLock_);
114 for (auto& profile : onDemandSaProfiles_) {
115 // start on demand
116 for (auto iterStart = profile.startOnDemand.onDemandEvents.begin();
117 iterStart != profile.startOnDemand.onDemandEvents.end(); iterStart++) {
118 if (IsSameEvent(event, *iterStart) && CheckConditions(*iterStart) &&
119 CheckExtraMessages(event, *iterStart)) {
120 // maybe the process is being killed, let samgr make decisions.
121 SaControlInfo control = { START_ON_DEMAND, profile.saId, iterStart->enableOnce,
122 iterStart->loadPriority };
123 saControlList.emplace_back(control);
124 break;
125 }
126 }
127 // stop on demand
128 for (auto iterStop = profile.stopOnDemand.onDemandEvents.begin();
129 iterStop != profile.stopOnDemand.onDemandEvents.end(); iterStop++) {
130 if (IsSameEvent(event, *iterStop) && CheckConditions(*iterStop) &&
131 CheckExtraMessages(event, *iterStop)) {
132 // maybe the process is starting, let samgr make decisions.
133 SaControlInfo control = { STOP_ON_DEMAND, profile.saId, iterStop->enableOnce,
134 iterStop->loadPriority };
135 saControlList.emplace_back(control);
136 break;
137 }
138 }
139 }
140 HILOGD("DeviceStatusCollectManager saControlList size %{public}zu", saControlList.size());
141 }
142
SortSaControlListByLoadPriority(std::list<SaControlInfo> & saControlList)143 void DeviceStatusCollectManager::SortSaControlListByLoadPriority(std::list<SaControlInfo>& saControlList)
144 {
145 saControlList.sort([](const SaControlInfo& control1, const SaControlInfo& control2) {
146 return control1.loadPriority < control2.loadPriority;
147 });
148 }
149
IsSameEvent(const OnDemandEvent & ev1,const OnDemandEvent & ev2)150 bool DeviceStatusCollectManager::IsSameEvent(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
151 {
152 return (ev1.eventId == ev2.eventId && ev1.name == ev2.name &&
153 ev1.persistence == ev2.persistence && (ev1.value == ev2.value || "" == ev2.value));
154 }
155
IsSameEventName(const OnDemandEvent & ev1,const OnDemandEvent & ev2)156 bool DeviceStatusCollectManager::IsSameEventName(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
157 {
158 if (ev1.eventId != TIMED_EVENT) {
159 if (ev1.eventId == ev2.eventId && ev1.name == ev2.name) {
160 return true;
161 }
162 } else {
163 if (ev1.eventId == ev2.eventId && ev1.name == ev2.name && ev1.value == ev2.value &&
164 ev1.persistence == ev2.persistence) {
165 return true;
166 }
167 }
168 return false;
169 }
170
CheckConditions(const OnDemandEvent & onDemandEvent)171 bool DeviceStatusCollectManager::CheckConditions(const OnDemandEvent& onDemandEvent)
172 {
173 if (onDemandEvent.conditions.empty()) {
174 return true;
175 }
176 for (auto& condition : onDemandEvent.conditions) {
177 if (collectPluginMap_.count(condition.eventId) == 0) {
178 HILOGE("not support condition: %{public}d", condition.eventId);
179 return false;
180 }
181 if (collectPluginMap_[condition.eventId] == nullptr) {
182 HILOGE("not support condition: %{public}d", condition.eventId);
183 return false;
184 }
185 bool ret = collectPluginMap_[condition.eventId]->CheckCondition(condition);
186 if (!ret) {
187 HILOGW("CheckCondition condition: %{public}s, value: %{public}s not pass",
188 condition.name.c_str(), condition.value.c_str());
189 return false;
190 }
191 }
192 return true;
193 }
194
CheckExtraMessages(const OnDemandEvent & ev1,const OnDemandEvent & ev2)195 bool DeviceStatusCollectManager::CheckExtraMessages(const OnDemandEvent& ev1, const OnDemandEvent& ev2)
196 {
197 HILOGD("CheckExtraMessages begin evt1:%{public}d, evt2:%{public}d", ev1.eventId, ev2.eventId);
198 if (collectPluginMap_.count(ev1.eventId) == 0) {
199 HILOGE("not support CheckExtraMessages");
200 return false;
201 }
202 if (collectPluginMap_[ev1.eventId] == nullptr) {
203 HILOGE("CommonEventCollect is nullptr");
204 return false;
205 }
206 if (collectPluginMap_[ev1.eventId]->CheckExtraMessage(ev1.extraDataId, ev2)) {
207 return true;
208 }
209 return false;
210 }
211
UnInit()212 void DeviceStatusCollectManager::UnInit()
213 {
214 for (auto& iter : collectPluginMap_) {
215 if (iter.second != nullptr) {
216 iter.second->OnStop();
217 }
218 }
219 collectPluginMap_.clear();
220
221 if (collectHandler_ != nullptr) {
222 collectHandler_ = nullptr;
223 }
224 }
225
CleanFfrt()226 void DeviceStatusCollectManager::CleanFfrt()
227 {
228 for (auto& iter : collectPluginMap_) {
229 if (iter.first == DEVICE_ONLINE || iter.first == COMMON_EVENT) {
230 iter.second->CleanFfrt();
231 }
232 }
233 if (collectHandler_ != nullptr) {
234 collectHandler_->CleanFfrt();
235 }
236 }
237
SetFfrt()238 void DeviceStatusCollectManager::SetFfrt()
239 {
240 for (auto& iter : collectPluginMap_) {
241 if (iter.first == DEVICE_ONLINE || iter.first == COMMON_EVENT) {
242 iter.second->SetFfrt();
243 }
244 }
245 if (collectHandler_ != nullptr) {
246 collectHandler_->SetFfrt("collect");
247 }
248 }
249
StartCollect()250 void DeviceStatusCollectManager::StartCollect()
251 {
252 HILOGI("DeviceStatusCollectManager OnStart begin");
253 if (collectHandler_ == nullptr) {
254 return;
255 }
256 auto callback = [this] () {
257 for (auto& iter : collectPluginMap_) {
258 iter.second->OnStart();
259 }
260 };
261 collectHandler_->PostTask(callback);
262 }
263
ReportEvent(const OnDemandEvent & event)264 void DeviceStatusCollectManager::ReportEvent(const OnDemandEvent& event)
265 {
266 if (collectHandler_ == nullptr) {
267 HILOGW("DeviceStatusCollectManager collectHandler_ is nullptr");
268 return;
269 }
270 std::list<SaControlInfo> saControlList;
271 GetSaControlListByEvent(event, saControlList);
272 GetSaControlListByPersistEvent(event, saControlList);
273 SortSaControlListByLoadPriority(saControlList);
274 if (saControlList.empty()) {
275 HILOGD("DeviceStatusCollectManager no matched event");
276 return;
277 }
278 auto callback = [event, saControlList = std::move(saControlList)] () {
279 SystemAbilityManager::GetInstance()->ProcessOnDemandEvent(event, saControlList);
280 };
281 collectHandler_->PostTask(callback);
282 }
283
PostDelayTask(std::function<void ()> callback,int32_t delayTime)284 void DeviceStatusCollectManager::PostDelayTask(std::function<void()> callback, int32_t delayTime)
285 {
286 HILOGI("DeviceStatusCollectManager PostDelayTask begin");
287 if (delayTime < 0 || delayTime > std::numeric_limits<int32_t>::max() / TO_MILLISECOND) {
288 HILOGE("DeviceStatusCollectManager PostDelayTask Failed : delayTime out of range %{public}d", delayTime);
289 return;
290 }
291 collectHandler_->PostTask(callback, delayTime * TO_MILLISECOND);
292 }
293
GetOnDemandReasonExtraData(int64_t extraDataId,OnDemandReasonExtraData & extraData)294 int32_t DeviceStatusCollectManager::GetOnDemandReasonExtraData(int64_t extraDataId, OnDemandReasonExtraData& extraData)
295 {
296 HILOGD("DeviceStatusCollectManager GetOnDemandReasonExtraData begin, extraDataId:%{public}d",
297 static_cast<int32_t>(extraDataId));
298 if (collectPluginMap_.count(COMMON_EVENT) == 0) {
299 HILOGE("not support get extra data");
300 return ERR_INVALID_VALUE;
301 }
302 if (collectPluginMap_[COMMON_EVENT] == nullptr) {
303 HILOGE("CommonEventCollect is nullptr");
304 return ERR_INVALID_VALUE;
305 }
306 if (!collectPluginMap_[COMMON_EVENT]->GetOnDemandReasonExtraData(extraDataId, extraData)) {
307 HILOGE("get extra data failed");
308 return ERR_INVALID_VALUE;
309 }
310 return ERR_OK;
311 }
312
AddCollectEvents(const std::vector<OnDemandEvent> & events)313 int32_t DeviceStatusCollectManager::AddCollectEvents(const std::vector<OnDemandEvent>& events)
314 {
315 if (events.size() == 0) {
316 return ERR_OK;
317 }
318 for (auto& event : events) {
319 if (collectPluginMap_.count(event.eventId) == 0) {
320 HILOGE("not support eventId: %{public}d", event.eventId);
321 return ERR_INVALID_VALUE;
322 }
323 if (collectPluginMap_[event.eventId] == nullptr) {
324 HILOGE("not support eventId: %{public}d", event.eventId);
325 return ERR_INVALID_VALUE;
326 }
327 int32_t ret = collectPluginMap_[event.eventId]->AddCollectEvent(event);
328 if (ret != ERR_OK) {
329 HILOGE("add collect event failed, eventId: %{public}d", event.eventId);
330 return ret;
331 }
332 }
333 return ERR_OK;
334 }
335
GetOnDemandEvents(int32_t systemAbilityId,OnDemandPolicyType type,std::vector<OnDemandEvent> & events)336 int32_t DeviceStatusCollectManager::GetOnDemandEvents(int32_t systemAbilityId, OnDemandPolicyType type,
337 std::vector<OnDemandEvent>& events)
338 {
339 HILOGI("DeviceStatusCollectManager GetOnDemandEvents begin");
340 std::shared_lock<std::shared_mutex> readLock(saProfilesLock_);
341 auto iter = std::find_if(onDemandSaProfiles_.begin(), onDemandSaProfiles_.end(), [systemAbilityId](auto saProfile) {
342 return saProfile.saId == systemAbilityId;
343 });
344 if (iter == onDemandSaProfiles_.end()) {
345 HILOGI("DeviceStatusCollectManager GetOnDemandEvents invalid saId:%{public}d", systemAbilityId);
346 return ERR_INVALID_VALUE;
347 }
348 if (type == OnDemandPolicyType::START_POLICY) {
349 events = (*iter).startOnDemand.onDemandEvents;
350 } else if (type == OnDemandPolicyType::STOP_POLICY) {
351 events = (*iter).stopOnDemand.onDemandEvents;
352 } else {
353 HILOGE("DeviceStatusCollectManager GetOnDemandEvents invalid policy types");
354 return ERR_INVALID_VALUE;
355 }
356 return ERR_OK;
357 }
358
RemoveUnusedEventsLocked(const std::vector<OnDemandEvent> & events)359 int32_t DeviceStatusCollectManager::RemoveUnusedEventsLocked(const std::vector<OnDemandEvent>& events)
360 {
361 HILOGD("DeviceStatusCollectManager RemoveUnusedEventsLocked start");
362 if (events.size() == 0) {
363 return ERR_OK;
364 }
365 for (auto& event : events) {
366 if (collectPluginMap_.count(event.eventId) == 0) {
367 HILOGE("not support eventId: %{public}d", event.eventId);
368 continue;
369 }
370 if (collectPluginMap_[event.eventId] == nullptr) {
371 HILOGE("not support eventId: %{public}d", event.eventId);
372 continue;
373 }
374 bool eventUsed = CheckEventUsedLocked(event);
375 if (!eventUsed) {
376 HILOGI("DeviceStatusCollectManager CheckEventUsedLocked name: %{public}s", event.name.c_str());
377 int32_t ret = collectPluginMap_[event.eventId]->RemoveUnusedEvent(event);
378 if (ret != ERR_OK) {
379 HILOGE("Remove event failed, eventId: %{public}d", event.eventId);
380 }
381 }
382 }
383 return ERR_OK;
384 }
385
CheckEventUsedLocked(const OnDemandEvent & event)386 bool DeviceStatusCollectManager::CheckEventUsedLocked(const OnDemandEvent& event)
387 {
388 for (auto& profile : onDemandSaProfiles_) {
389 // start on demand
390 for (auto iterStart = profile.startOnDemand.onDemandEvents.begin();
391 iterStart != profile.startOnDemand.onDemandEvents.end(); iterStart++) {
392 if (IsSameEventName(event, *iterStart)) {
393 return true;
394 }
395 }
396 // stop on demand
397 for (auto iterStop = profile.stopOnDemand.onDemandEvents.begin();
398 iterStop != profile.stopOnDemand.onDemandEvents.end(); iterStop++) {
399 if (IsSameEventName(event, *iterStop)) {
400 return true;
401 }
402 }
403 }
404 return false;
405 }
406
NeedPersistOnDemandEvent(const OnDemandEvent & event)407 bool DeviceStatusCollectManager::NeedPersistOnDemandEvent(const OnDemandEvent& event)
408 {
409 if (event.eventId == TIMED_EVENT && event.name == "timedevent" && event.persistence) {
410 return true;
411 }
412 return false;
413 }
414
PersistOnDemandEvent(int32_t systemAbilityId,OnDemandPolicyType type,const std::vector<OnDemandEvent> & events)415 void DeviceStatusCollectManager::PersistOnDemandEvent(int32_t systemAbilityId, OnDemandPolicyType type,
416 const std::vector<OnDemandEvent>& events)
417 {
418 #ifdef PREFERENCES_ENABLE
419 std::shared_ptr<PreferencesUtil> preferencesUtil = PreferencesUtil::GetInstance();
420 if (preferencesUtil == nullptr) {
421 return;
422 }
423 for (OnDemandEvent event : events) {
424 if (!NeedPersistOnDemandEvent(event)) {
425 continue;
426 }
427 std::string strEvent = event.ToString();
428 std::string strTypeAndSaid = TypeAndSaidToString(type, systemAbilityId);
429 if (preferencesUtil->IsExist(strEvent)) {
430 std::string orgStrTypeAndSaid = preferencesUtil->ObtainString(strEvent, "");
431 orgStrTypeAndSaid += "+";
432 orgStrTypeAndSaid += strTypeAndSaid;
433 HILOGI("PersistOnDemandEvent Save orgStrTypeAndSaid is : %{public}s", orgStrTypeAndSaid.c_str());
434 preferencesUtil->SaveString(strEvent, orgStrTypeAndSaid);
435 } else {
436 preferencesUtil->SaveString(strEvent, strTypeAndSaid);
437 HILOGI("PersistOnDemandEvent Save strTypeAndSaid is : %{public}s", strTypeAndSaid.c_str());
438 }
439 }
440 #endif
441 }
442
TypeAndSaidToString(OnDemandPolicyType type,int32_t systemAbilityId)443 std::string DeviceStatusCollectManager::TypeAndSaidToString(OnDemandPolicyType type, int32_t systemAbilityId)
444 {
445 std::string strSaid = std::to_string(systemAbilityId);
446 if (type == OnDemandPolicyType::START_POLICY) {
447 return "start#" + strSaid + "#";
448 } else if (type == OnDemandPolicyType::STOP_POLICY) {
449 return "stop#" + strSaid + "#";
450 }
451 return "";
452 }
453
StringToTypeAndSaid(const std::string & eventStr,OnDemandPolicyType & type,int32_t & systemAbilityId)454 void DeviceStatusCollectManager::StringToTypeAndSaid(const std::string& eventStr, OnDemandPolicyType& type,
455 int32_t& systemAbilityId)
456 {
457 std::size_t pos = eventStr.find("#");
458 std::string strType = eventStr.substr(0, pos);
459 if (strType == "start") {
460 type = OnDemandPolicyType::START_POLICY;
461 } else if (strType == "stop") {
462 type = OnDemandPolicyType::STOP_POLICY;
463 } else {
464 HILOGW("DeviceStatusCollectManager StringToTypeAndSaid failed");
465 return;
466 }
467 systemAbilityId = atoi((eventStr.substr(pos + 1, eventStr.size() - pos - 1)).c_str());
468 HILOGD("systemAbilityId is : %{public}d", systemAbilityId);
469 }
470
UpdateOnDemandEvents(int32_t systemAbilityId,OnDemandPolicyType type,const std::vector<OnDemandEvent> & events)471 int32_t DeviceStatusCollectManager::UpdateOnDemandEvents(int32_t systemAbilityId, OnDemandPolicyType type,
472 const std::vector<OnDemandEvent>& events)
473 {
474 HILOGI("DeviceStatusCollectManager UpdateOnDemandEvents begin");
475 std::unique_lock<std::shared_mutex> writeLock(saProfilesLock_);
476 auto iter = std::find_if(onDemandSaProfiles_.begin(), onDemandSaProfiles_.end(), [systemAbilityId](auto saProfile) {
477 return saProfile.saId == systemAbilityId;
478 });
479 if (iter == onDemandSaProfiles_.end()) {
480 HILOGI("DeviceStatusCollectManager UpdateOnDemandEvents invalid saId:%{public}d", systemAbilityId);
481 return ERR_INVALID_VALUE;
482 }
483 if (AddCollectEvents(events) != ERR_OK) {
484 HILOGI("DeviceStatusCollectManager AddCollectEvents failed saId:%{public}d", systemAbilityId);
485 return ERR_INVALID_VALUE;
486 }
487 std::vector<OnDemandEvent> oldEvents;
488 if (type == OnDemandPolicyType::START_POLICY) {
489 oldEvents = (*iter).startOnDemand.onDemandEvents;
490 (*iter).startOnDemand.onDemandEvents = events;
491 } else if (type == OnDemandPolicyType::STOP_POLICY) {
492 oldEvents = (*iter).stopOnDemand.onDemandEvents;
493 (*iter).stopOnDemand.onDemandEvents = events;
494 } else {
495 HILOGE("DeviceStatusCollectManager UpdateOnDemandEvents policy types");
496 return ERR_INVALID_VALUE;
497 }
498 PersistOnDemandEvent(systemAbilityId, type, events);
499 if (RemoveUnusedEventsLocked(oldEvents) != ERR_OK) {
500 HILOGE("DeviceStatusCollectManager RemoveUnusedEventsLocked failed saId:%{public}d", systemAbilityId);
501 }
502 return ERR_OK;
503 }
504 } // namespace OHOS
505