1 /*
2  * Copyright (c) 2024 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 "media_monitor_policy.h"
17 #include "log.h"
18 #include "parameter.h"
19 #include "parameters.h"
20 
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FOUNDATION, "MediaMonitorPolicy"};
23 }
24 
25 namespace OHOS {
26 namespace Media {
27 namespace MediaMonitor {
28 
29 static constexpr int32_t INITIAL_VALUE = 1;
30 
MediaMonitorPolicy()31 MediaMonitorPolicy::MediaMonitorPolicy()
32     : mediaEventBaseWriter_(MediaEventBaseWriter::GetMediaEventBaseWriter())
33 {
34     MEDIA_LOG_D("MediaMonitorPolicy Constructor");
35     ReadParameter();
36     StartTimeThread();
37 }
38 
~MediaMonitorPolicy()39 MediaMonitorPolicy::~MediaMonitorPolicy()
40 {
41     MEDIA_LOG_D("MediaMonitorPolicy Destructor");
42     StopTimeThread();
43 }
44 
ReadParameter()45 void MediaMonitorPolicy::ReadParameter()
46 {
47     const int32_t length = 6;
48     char aggregationFrequency[length] = {0};
49     char aggregationTime[length] = {0};
50     int32_t ret = GetParameter("persist.multimedia.mediafoundation.aggregationfrequency", "1000",
51         aggregationFrequency, sizeof(aggregationFrequency) - 1);
52     if (ret > 0) {
53         aggregationFrequency_ = atoi(aggregationFrequency);
54         MEDIA_LOG_I("Get aggregationFrequency_ success %{public}d", aggregationFrequency_);
55     } else {
56         MEDIA_LOG_E("Get aggregationFrequency_ failed %{public}d", ret);
57     }
58 
59     ret = GetParameter("persist.multimedia.mediafoundation.aggregationtime", "1440",
60         aggregationTime, sizeof(aggregationTime) - 1);
61     if (ret > 0) {
62         aggregationTime_ = atoi(aggregationTime);
63         MEDIA_LOG_I("Get aggregationTime_ success %{public}d", aggregationTime_);
64     } else {
65         MEDIA_LOG_E("Get aggregationTime_ failed %{public}d", ret);
66     }
67 }
68 
TimeFunc()69 void MediaMonitorPolicy::TimeFunc()
70 {
71     while (startThread_.load(std::memory_order_acquire)) {
72         curruntTime_ = TimeUtils::GetCurSec();
73         std::this_thread::sleep_for(std::chrono::minutes(aggregationTime_));
74         HandleToHiSysEvent();
75     }
76 }
77 
StartTimeThread()78 void MediaMonitorPolicy::StartTimeThread()
79 {
80     timeThread_ = std::make_unique<std::thread>(&MediaMonitorPolicy::TimeFunc, this);
81     pthread_setname_np(timeThread_->native_handle(), "DFXTiming");
82 }
83 
StopTimeThread()84 void MediaMonitorPolicy::StopTimeThread()
85 {
86     startThread_.store(false, std::memory_order_release);
87 }
88 
WriteEvent(EventId eventId,std::shared_ptr<EventBean> & bean)89 void MediaMonitorPolicy::WriteEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
90 {
91     MEDIA_LOG_D("Write event");
92     if (bean == nullptr) {
93         MEDIA_LOG_E("eventBean is nullptr");
94         return;
95     }
96     if (bean->GetEventType() == BEHAVIOR_EVENT) {
97         WriteBehaviorEvent(eventId, bean);
98     } else if (bean->GetEventType() == FAULT_EVENT) {
99         WriteFaultEvent(eventId, bean);
100     } else {
101         WriteAggregationEvent(eventId, bean);
102     }
103 }
104 
WriteBehaviorEvent(EventId eventId,std::shared_ptr<EventBean> & bean)105 void MediaMonitorPolicy::WriteBehaviorEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
106 {
107     MEDIA_LOG_D("Write behavior event");
108     switch (eventId) {
109         case DEVICE_CHANGE:
110             mediaEventBaseWriter_.WriteDeviceChange(bean);
111             break;
112         case HEADSET_CHANGE:
113             mediaEventBaseWriter_.WriteHeasetChange(bean);
114             break;
115         case STREAM_CHANGE:
116             mediaEventBaseWriter_.WriteStreamChange(bean);
117             break;
118         case VOLUME_CHANGE:
119             mediaEventBaseWriter_.WriteVolumeChange(bean);
120             break;
121         case AUDIO_ROUTE_CHANGE:
122             mediaEventBaseWriter_.WriteAudioRouteChange(bean);
123             break;
124         case AUDIO_PIPE_CHANGE:
125             mediaEventBaseWriter_.WriteAudioPipeChange(bean);
126             break;
127         case AUDIO_FOCUS_MIGRATE:
128             mediaEventBaseWriter_.WriteFocusMigrate(bean);
129             break;
130         case SET_FORCE_USE_AUDIO_DEVICE:
131             mediaEventBaseWriter_.WriteSetForceDevice(bean);
132             break;
133         case BACKGROUND_SILENT_PLAYBACK:
134             mediaEventBaseWriter_.WriteBGSilentPlayback(bean);
135             break;
136         case STREAM_STANDBY:
137             mediaEventBaseWriter_.WriteStreamStandby(bean);
138             break;
139         default:
140             break;
141     }
142 }
143 
WriteFaultEvent(EventId eventId,std::shared_ptr<EventBean> & bean)144 void MediaMonitorPolicy::WriteFaultEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
145 {
146     MEDIA_LOG_D("Write fault event");
147     switch (eventId) {
148         case LOAD_CONFIG_ERROR:
149             mediaEventBaseWriter_.WriteLoadConfigError(bean);
150             break;
151         case AUDIO_SERVICE_STARTUP_ERROR:
152             mediaEventBaseWriter_.WriteAudioStartupError(bean);
153             break;
154         case LOAD_EFFECT_ENGINE_ERROR:
155             mediaEventBaseWriter_.WriteLoadEffectEngineError(bean);
156             break;
157         default:
158             break;
159     }
160 }
161 
WriteAggregationEvent(EventId eventId,std::shared_ptr<EventBean> & bean)162 void MediaMonitorPolicy::WriteAggregationEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
163 {
164     MEDIA_LOG_D("Write aggregation event");
165     switch (eventId) {
166         case AUDIO_STREAM_EXHAUSTED_STATS:
167             mediaEventBaseWriter_.WriteStreamExhastedError(bean);
168             break;
169         case AUDIO_STREAM_CREATE_ERROR_STATS:
170             mediaEventBaseWriter_.WriteStreamCreateError(bean);
171             break;
172         case BACKGROUND_SILENT_PLAYBACK:
173             mediaEventBaseWriter_.WriteBackgoundSilentPlayback(bean);
174             break;
175         case STREAM_UTILIZATION_STATS:
176             mediaEventBaseWriter_.WriteStreamStatistic(bean);
177             break;
178         case STREAM_PROPERTY_STATS:
179             mediaEventBaseWriter_.WriteStreamPropertyStatistic(bean);
180             break;
181         case AUDIO_DEVICE_UTILIZATION_STATS:
182              mediaEventBaseWriter_.WriteDeviceStatistic(bean);
183             break;
184         case BT_UTILIZATION_STATS:
185             mediaEventBaseWriter_.WriteBtUsageStatistic(bean);
186             break;
187         case PERFORMANCE_UNDER_OVERRUN_STATS:
188             mediaEventBaseWriter_.WriteUnderrunStatistic(bean);
189             break;
190         case PLAYBACK_VOLUME_STATS:
191             mediaEventBaseWriter_.WritePlaybackVolume(bean);
192             break;
193         case MUTED_CAPTURE_STATS:
194             mediaEventBaseWriter_.WriteMutedCapture(bean);
195             break;
196         default:
197             break;
198     }
199 }
200 
HandDeviceUsageToEventVector(std::shared_ptr<EventBean> & deviceUsage)201 void MediaMonitorPolicy::HandDeviceUsageToEventVector(std::shared_ptr<EventBean> &deviceUsage)
202 {
203     MEDIA_LOG_I("Handle device usage to event vector");
204     if (deviceUsage == nullptr) {
205         MEDIA_LOG_E("MediaMonitorPolicy HandDeviceUsageToEventVector deviceUsage is nullpr");
206         return;
207     }
208     bool isInEventMap = false;
209     auto isExist = [&deviceUsage](const std::shared_ptr<EventBean> &eventBean) {
210         if (eventBean->GetEventId() == AUDIO_DEVICE_UTILIZATION_STATS &&
211             deviceUsage->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
212             deviceUsage->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
213             deviceUsage->GetIntValue("DEVICE_TYPE") == eventBean->GetIntValue("DEVICE_TYPE")) {
214             MEDIA_LOG_D("Find the existing device usage");
215             return true;
216         }
217         return false;
218     };
219     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
220     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
221     if (it != eventVector_.end()) {
222         uint64_t duration = (*it)->GetUint64Value("DURATION") + deviceUsage->GetUint64Value("DURATION");
223         (*it)->UpdateUint64Map("DURATION", duration);
224         isInEventMap = true;
225     }
226 
227     if (!isInEventMap) {
228         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
229             EventId::AUDIO_DEVICE_UTILIZATION_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
230         eventBean->Add("STREAM_TYPE", deviceUsage->GetIntValue("STREAM_TYPE"));
231         eventBean->Add("DEVICE_TYPE", deviceUsage->GetIntValue("DEVICE_TYPE"));
232         eventBean->Add("IS_PLAYBACK", deviceUsage->GetIntValue("IS_PLAYBACK"));
233         eventBean->Add("DURATION", deviceUsage->GetUint64Value("DURATION"));
234         AddToEventVector(eventBean);
235     }
236 }
237 
HandBtUsageToEventVector(std::shared_ptr<EventBean> & btUsage)238 void MediaMonitorPolicy::HandBtUsageToEventVector(std::shared_ptr<EventBean> &btUsage)
239 {
240     MEDIA_LOG_I("Handle bt usage to event vector");
241     if (btUsage == nullptr) {
242         MEDIA_LOG_I("MediaMonitorPolicy HandBtUsageToEventVector btUsage is nullpr");
243         return;
244     }
245     bool isInEventMap = false;
246     auto isExist = [&btUsage](const std::shared_ptr<EventBean> &eventBean) {
247         if (eventBean->GetEventId() == BT_UTILIZATION_STATS &&
248             btUsage->GetIntValue("BT_TYPE") == eventBean->GetIntValue("BT_TYPE") &&
249             btUsage->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
250             btUsage->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK")) {
251             MEDIA_LOG_I("Find the existing bt device usage");
252             return true;
253         }
254         return false;
255     };
256     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
257     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
258     if (it != eventVector_.end()) {
259         uint64_t duration = (*it)->GetUint64Value("DURATION") + btUsage->GetUint64Value("DURATION");
260         (*it)->UpdateUint64Map("DURATION", duration);
261         isInEventMap = true;
262     }
263 
264     if (!isInEventMap) {
265         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
266             EventId::BT_UTILIZATION_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
267         eventBean->Add("BT_TYPE", btUsage->GetIntValue("BT_TYPE"));
268         eventBean->Add("IS_PLAYBACK", btUsage->GetIntValue("IS_PLAYBACK"));
269         eventBean->Add("STREAM_TYPE", btUsage->GetIntValue("STREAM_TYPE"));
270         eventBean->Add("DURATION", btUsage->GetUint64Value("DURATION"));
271         AddToEventVector(eventBean);
272     }
273 }
274 
HandStreamUsageToEventVector(std::shared_ptr<EventBean> & streamUsage)275 void MediaMonitorPolicy::HandStreamUsageToEventVector(std::shared_ptr<EventBean> &streamUsage)
276 {
277     MEDIA_LOG_I("Handle stream usage to event vector");
278     if (streamUsage == nullptr) {
279         MEDIA_LOG_E("MediaMonitorPolicy HandStreamUsageToEventVector streamUsage is nullpr");
280         return;
281     }
282     bool isInEventMap = false;
283     auto isExist = [&streamUsage](const std::shared_ptr<EventBean> &eventBean) {
284         if (eventBean->GetEventId() == STREAM_UTILIZATION_STATS &&
285             streamUsage->GetIntValue("PIPE_TYPE") == eventBean->GetIntValue("PIPE_TYPE") &&
286             streamUsage->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
287             streamUsage->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
288             streamUsage->GetStringValue("APP_NAME") == eventBean->GetStringValue("APP_NAME") &&
289             streamUsage->GetIntValue("SAMPLE_RATE") == eventBean->GetIntValue("SAMPLE_RATE")) {
290             MEDIA_LOG_I("Find the existing stream usage");
291             return true;
292         }
293         return false;
294     };
295     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
296     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
297     if (it != eventVector_.end()) {
298         uint64_t duration = (*it)->GetUint64Value("DURATION") + streamUsage->GetUint64Value("DURATION");
299         (*it)->UpdateUint64Map("DURATION", duration);
300         isInEventMap = true;
301     }
302     if (!isInEventMap) {
303         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
304             EventId::STREAM_UTILIZATION_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
305         eventBean->Add("PIPE_TYPE", streamUsage->GetIntValue("PIPE_TYPE"));
306         eventBean->Add("IS_PLAYBACK", streamUsage->GetIntValue("IS_PLAYBACK"));
307         eventBean->Add("STREAM_TYPE", streamUsage->GetIntValue("STREAM_TYPE"));
308         eventBean->Add("SAMPLE_RATE", streamUsage->GetIntValue("SAMPLE_RATE"));
309         eventBean->Add("APP_NAME", streamUsage->GetStringValue("APP_NAME"));
310         eventBean->Add("EFFECT_CHAIN", streamUsage->GetIntValue("EFFECT_CHAIN"));
311         eventBean->Add("DURATION", streamUsage->GetUint64Value("DURATION"));
312         AddToEventVector(eventBean);
313     }
314 }
315 
HandStreamPropertyToEventVector(std::shared_ptr<EventBean> & streamProperty)316 void MediaMonitorPolicy::HandStreamPropertyToEventVector(std::shared_ptr<EventBean> &streamProperty)
317 {
318     MEDIA_LOG_I("Handle stream property to event vector");
319     if (streamProperty == nullptr) {
320         MEDIA_LOG_E("MediaMonitorPolicy HandStreamPropertyToEventVector streamProperty is nullptr");
321         return;
322     }
323     bool isInEventMap = false;
324     auto isExist = [&streamProperty](const std::shared_ptr<EventBean> &eventBean) {
325         if (eventBean->GetEventId() == STREAM_UTILIZATION_STATS &&
326             streamProperty->GetIntValue("UID") == eventBean->GetIntValue("UID") &&
327             streamProperty->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
328             streamProperty->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
329             streamProperty->GetStringValue("APP_NAME") == eventBean->GetStringValue("APP_NAME") &&
330             streamProperty->GetIntValue("CHANNEL_LAYOUT") ==
331             static_cast<int64_t>(eventBean->GetUint64Value("CHANNEL_LAYOUT")) &&
332             streamProperty->GetIntValue("ENCODING_TYPE") == eventBean->GetIntValue("ENCODING_TYPE")) {
333             MEDIA_LOG_I("Find the existing stream property");
334             return true;
335         }
336         return false;
337     };
338     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
339     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
340     if (it != eventVector_.end()) {
341         uint64_t duration = (*it)->GetUint64Value("DURATION") + streamProperty->GetUint64Value("DURATION");
342         (*it)->UpdateUint64Map("DURATION", duration);
343         isInEventMap = true;
344     }
345 
346     if (!isInEventMap) {
347         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
348             EventId::STREAM_PROPERTY_STATS, EventType::DURATION_AGGREGATION_EVENT);
349 
350         eventBean->Add("IS_PLAYBACK", streamProperty->GetIntValue("IS_PLAYBACK"));
351         eventBean->Add("STREAM_TYPE", streamProperty->GetIntValue("STREAM_TYPE"));
352         eventBean->Add("APP_NAME", streamProperty->GetStringValue("APP_NAME"));
353         eventBean->Add("ENCODING_TYPE", streamProperty->GetIntValue("ENCODING_TYPE"));
354         eventBean->Add("CHANNEL_LAYOUT", streamProperty->GetUint64Value("CHANNEL_LAYOUT"));
355         eventBean->Add("DURATION", streamProperty->GetUint64Value("DURATION"));
356         AddToEventVector(eventBean);
357     }
358 }
359 
HandleVolumeToEventVector(std::shared_ptr<EventBean> & bean)360 void MediaMonitorPolicy::HandleVolumeToEventVector(std::shared_ptr<EventBean> &bean)
361 {
362     MEDIA_LOG_I("Handle volume to event vector");
363     if (bean == nullptr) {
364         MEDIA_LOG_E("MediaMonitorPolicy HandleVolumeToEventVector bean is nullpr");
365         return;
366     }
367     bool isInEventMap = false;
368     auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
369         if (eventBean->GetEventId() == PLAYBACK_VOLUME_STATS &&
370             bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
371             bean->GetIntValue("LEVEL") == eventBean->GetIntValue("LEVEL") &&
372             bean->GetIntValue("DEVICE_TYPE") == eventBean->GetIntValue("DEVICE_TYPE")) {
373             MEDIA_LOG_D("Find the existing volume usage");
374             return true;
375         }
376         return false;
377     };
378 
379     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
380     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
381     if (it != eventVector_.end()) {
382         uint64_t duration = (*it)->GetUint64Value("DURATION") + bean->GetUint64Value("DURATION");
383         (*it)->UpdateUint64Map("DURATION", duration);
384         isInEventMap = true;
385     }
386 
387     if (!isInEventMap) {
388         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
389             EventId::PLAYBACK_VOLUME_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
390         eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
391         eventBean->Add("LEVEL", bean->GetIntValue("LEVEL"));
392         eventBean->Add("DEVICE_TYPE", bean->GetIntValue("DEVICE_TYPE"));
393         eventBean->Add("DURATION", bean->GetUint64Value("DURATION"));
394         AddToEventVector(eventBean);
395     }
396 }
397 
HandleCaptureMutedToEventVector(std::shared_ptr<EventBean> & bean)398 void MediaMonitorPolicy::HandleCaptureMutedToEventVector(std::shared_ptr<EventBean> &bean)
399 {
400     MEDIA_LOG_I("Handle capture muted to event vector");
401     if (bean == nullptr) {
402         MEDIA_LOG_E("MediaMonitorPolicy HandleCaptureMutedToEventVector bean is nullpr");
403         return;
404     }
405     bool isInEventMap = false;
406     auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
407         if (eventBean->GetEventId() == MUTED_CAPTURE_STATS &&
408             bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
409             bean->GetIntValue("DEVICE_TYPE") == eventBean->GetIntValue("DEVICE_TYPE")) {
410             MEDIA_LOG_I("Find the existing capture muted");
411             return true;
412         }
413         return false;
414     };
415     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
416     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
417     if (it != eventVector_.end()) {
418         uint64_t duration = (*it)->GetUint64Value("DURATION") + bean->GetUint64Value("DURATION");
419         (*it)->UpdateUint64Map("DURATION", duration);
420         isInEventMap = true;
421     }
422 
423     if (!isInEventMap) {
424         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
425             EventId::MUTED_CAPTURE_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
426         eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
427         eventBean->Add("DEVICE_TYPE", bean->GetIntValue("DEVICE_TYPE"));
428         eventBean->Add("DURATION", bean->GetUint64Value("DURATION"));
429         AddToEventVector(eventBean);
430     }
431 }
432 
HandleExhaustedToEventVector(std::shared_ptr<EventBean> & bean)433 void MediaMonitorPolicy::HandleExhaustedToEventVector(std::shared_ptr<EventBean> &bean)
434 {
435     MEDIA_LOG_I("Handle exhausted to event map");
436     std::string appName = bean->GetStringValue("APP_NAME");
437     int32_t appStreamNum = bean->GetIntValue("STREAM_NUM");
438     MEDIA_LOG_I("Handle exhausted to event map, appName:%{public}s, appStreamNum: %{public}d",
439         appName.c_str(), appStreamNum);
440     bool isInEventMap = false;
441     auto isExist = [&appName](const std::shared_ptr<EventBean> &eventBean) {
442         if (eventBean->GetEventId() == AUDIO_STREAM_EXHAUSTED_STATS &&
443             appName == eventBean->GetStringValue("DUBIOUS_APP")) {
444             MEDIA_LOG_I("Find the existing DUBIOUS_APP");
445             return true;
446         }
447         return false;
448     };
449     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
450     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
451     if (it != eventVector_.end()) {
452         int32_t streamNum = (*it)->GetIntValue("TIMES");
453         if (appStreamNum > streamNum) {
454             (*it)->UpdateIntMap("TIMES", appStreamNum);
455         }
456         isInEventMap = true;
457     }
458     if (!isInEventMap) {
459         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
460             EventId::AUDIO_STREAM_EXHAUSTED_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
461         eventBean->Add("DUBIOUS_APP", appName);
462         eventBean->Add("TIMES", appStreamNum);
463         AddToEventVector(eventBean);
464     }
465 }
466 
HandleCreateErrorToEventVector(std::shared_ptr<EventBean> & bean)467 void MediaMonitorPolicy::HandleCreateErrorToEventVector(std::shared_ptr<EventBean> &bean)
468 {
469     MEDIA_LOG_I("Handle create error to event vector");
470     bool isInEventMap = false;
471     auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
472         if (eventBean->GetEventId() == AUDIO_STREAM_CREATE_ERROR_STATS &&
473             bean->GetStringValue("APP_NAME") == eventBean->GetStringValue("APP_NAME") &&
474             bean->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
475             bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
476             bean->GetIntValue("ERROR_CODE") == eventBean->GetIntValue("ERROR_CODE")) {
477             MEDIA_LOG_I("Find the existing create error app");
478             return true;
479         }
480         return false;
481     };
482     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
483     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
484     if (it != eventVector_.end()) {
485         int32_t num = (*it)->GetIntValue("TIMES");
486         (*it)->UpdateIntMap("TIMES", ++num);
487         isInEventMap = true;
488     }
489 
490     if (!isInEventMap) {
491         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
492             EventId::AUDIO_STREAM_CREATE_ERROR_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
493         eventBean->Add("APP_NAME", bean->GetStringValue("APP_NAME"));
494         eventBean->Add("IS_PLAYBACK", bean->GetIntValue("IS_PLAYBACK"));
495         eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
496         eventBean->Add("ERROR_CODE", bean->GetIntValue("ERROR_CODE"));
497         eventBean->Add("TIMES", INITIAL_VALUE);
498         AddToEventVector(eventBean);
499     }
500 }
501 
HandleSilentPlaybackToEventVector(std::shared_ptr<EventBean> & bean)502 void MediaMonitorPolicy::HandleSilentPlaybackToEventVector(std::shared_ptr<EventBean> &bean)
503 {
504     MEDIA_LOG_I("Handle silent playback to event vector");
505     bool isInEventMap = false;
506     auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
507         if (eventBean->GetEventId() == BACKGROUND_SILENT_PLAYBACK &&
508             bean->GetStringValue("APP_NAME") == eventBean->GetStringValue("APP_NAME") &&
509             bean->GetIntValue("APP_VERSION_CODE") == eventBean->GetIntValue("APP_VERSION_CODE")) {
510             MEDIA_LOG_I("Find the existing silent playback app");
511             return true;
512         }
513         return false;
514     };
515     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
516     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
517     if (it != eventVector_.end()) {
518         int32_t num = (*it)->GetIntValue("TIMES");
519         (*it)->UpdateIntMap("TIMES", ++num);
520         isInEventMap = true;
521     }
522     if (!isInEventMap) {
523         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
524             EventId::BACKGROUND_SILENT_PLAYBACK, EventType::FREQUENCY_AGGREGATION_EVENT);
525         eventBean->Add("APP_NAME", bean->GetStringValue("APP_NAME"));
526         eventBean->Add("APP_VERSION_CODE", bean->GetIntValue("APP_VERSION_CODE"));
527         eventBean->Add("TIMES", INITIAL_VALUE);
528         AddToEventVector(eventBean);
529     }
530 }
531 
HandleUnderrunToEventVector(std::shared_ptr<EventBean> & bean)532 void MediaMonitorPolicy::HandleUnderrunToEventVector(std::shared_ptr<EventBean> &bean)
533 {
534     MEDIA_LOG_I("Handle underrun to event vector");
535     bool isInEventMap = false;
536     auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
537         if (eventBean->GetEventId() == PERFORMANCE_UNDER_OVERRUN_STATS &&
538             bean->GetStringValue("APP_NAME") == eventBean->GetStringValue("APP_NAME") &&
539             bean->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
540             bean->GetIntValue("PIPE_TYPE") == eventBean->GetIntValue("PIPE_TYPE") &&
541             bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE")) {
542             MEDIA_LOG_I("Find the existing underrun app");
543             return true;
544         }
545         return false;
546     };
547     std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
548     auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
549     if (it != eventVector_.end()) {
550         int32_t num = (*it)->GetIntValue("TIMES");
551         (*it)->UpdateIntMap("TIMES", ++num);
552         isInEventMap = true;
553     }
554     if (!isInEventMap) {
555         std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
556             EventId::PERFORMANCE_UNDER_OVERRUN_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
557         eventBean->Add("APP_NAME", bean->GetStringValue("APP_NAME"));
558         eventBean->Add("IS_PLAYBACK", bean->GetIntValue("IS_PLAYBACK"));
559         eventBean->Add("PIPE_TYPE", bean->GetIntValue("PIPE_TYPE"));
560         eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
561         eventBean->Add("TIMES", INITIAL_VALUE);
562         AddToEventVector(eventBean);
563     }
564 }
565 
AddToEventVector(std::shared_ptr<EventBean> & bean)566 void MediaMonitorPolicy::AddToEventVector(std::shared_ptr<EventBean> &bean)
567 {
568     MEDIA_LOG_D("Add to event vector");
569     eventVector_.push_back(bean);
570 }
571 
WhetherToHiSysEvent()572 void MediaMonitorPolicy::WhetherToHiSysEvent()
573 {
574     MEDIA_LOG_D("eventVector size %{public}zu", eventVector_.size());
575     if (eventVector_.size() >= static_cast<uint32_t>(aggregationFrequency_)) {
576         std::unique_ptr<std::thread>  writeEventThread = std::make_unique<std::thread>(
577             &MediaMonitorPolicy::HandleToHiSysEvent, this);
578         pthread_setname_np(writeEventThread->native_handle(), "ToHiSysEvent");
579         writeEventThread->detach();
580     }
581 }
582 
HandleToHiSysEvent()583 void MediaMonitorPolicy::HandleToHiSysEvent()
584 {
585     MEDIA_LOG_D("Handle to hiSysEvent");
586     std::vector<std::shared_ptr<EventBean>> eventVector;
587     {
588         std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
589         eventVector = eventVector_;
590         eventVector_.clear();
591     }
592     for (auto &desc : eventVector) {
593         if (desc == nullptr) {
594             continue;
595         }
596         WriteEvent(desc->GetEventId(), desc);
597     }
598 }
599 
WriteInfo(int32_t fd,std::string & dumpString)600 void MediaMonitorPolicy::WriteInfo(int32_t fd, std::string &dumpString)
601 {
602     if (fd != -1) {
603         int32_t remainderSize = aggregationFrequency_ - static_cast<int32_t>(eventVector_.size());
604         int64_t elapsedTime = static_cast<int64_t>((TimeUtils::GetCurSec() - curruntTime_)) / 60;
605         int64_t oneDay = aggregationTime_;
606         dumpString += "Counting of eventVector entries:";
607         dumpString += "\n";
608         dumpString += "    The current number of eventVector: " + std::to_string(eventVector_.size());
609         dumpString += "\n";
610         dumpString += "    Remaining number of starting refreshes: " + std::to_string(remainderSize);
611         dumpString += "\n";
612         dumpString += "\n";
613         dumpString += "Time Count:";
614         dumpString += "\n";
615         dumpString += "    Time elapsed:" + std::to_string(elapsedTime) + "min";
616         dumpString += "\n";
617         dumpString += "    Remaining refresh time:" + std::to_string(oneDay - elapsedTime) + "min";
618         dumpString += "\n";
619         dumpString += "\n";
620     }
621 }
622 
623 } // namespace MediaMonitor
624 } // namespace Media
625 } // namespace OHOS