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 const int32_t MAX_PLAY_COUNT = 100;
31
MediaMonitorPolicy()32 MediaMonitorPolicy::MediaMonitorPolicy()
33 : mediaEventBaseWriter_(MediaEventBaseWriter::GetMediaEventBaseWriter())
34 {
35 MEDIA_LOG_D("MediaMonitorPolicy Constructor");
36 ReadParameter();
37 StartTimeThread();
38 }
39
~MediaMonitorPolicy()40 MediaMonitorPolicy::~MediaMonitorPolicy()
41 {
42 MEDIA_LOG_D("MediaMonitorPolicy Destructor");
43 StopTimeThread();
44 }
45
ReadParameter()46 void MediaMonitorPolicy::ReadParameter()
47 {
48 const int32_t length = 6;
49 char aggregationFrequency[length] = {0};
50 char aggregationTime[length] = {0};
51 int32_t ret = GetParameter("persist.multimedia.mediafoundation.aggregationfrequency", "1000",
52 aggregationFrequency, sizeof(aggregationFrequency) - 1);
53 if (ret > 0) {
54 aggregationFrequency_ = atoi(aggregationFrequency);
55 MEDIA_LOG_I("Get aggregationFrequency_ success %{public}d", aggregationFrequency_);
56 } else {
57 MEDIA_LOG_E("Get aggregationFrequency_ failed %{public}d", ret);
58 }
59
60 ret = GetParameter("persist.multimedia.mediafoundation.aggregationtime", "1440",
61 aggregationTime, sizeof(aggregationTime) - 1);
62 if (ret > 0) {
63 aggregationTime_ = atoi(aggregationTime);
64 MEDIA_LOG_I("Get aggregationTime_ success %{public}d", aggregationTime_);
65 } else {
66 MEDIA_LOG_E("Get aggregationTime_ failed %{public}d", ret);
67 }
68 }
69
TimeFunc()70 void MediaMonitorPolicy::TimeFunc()
71 {
72 while (startThread_.load(std::memory_order_acquire)) {
73 curruntTime_ = TimeUtils::GetCurSec();
74 std::this_thread::sleep_for(std::chrono::minutes(systemTonePlaybackTime_));
75 afterSleepTime_ = TimeUtils::GetCurSec();
76 if (afterSleepTime_ - lastAudioTime_ >= aggregationSleepTime_) {
77 HandleToHiSysEvent();
78 lastAudioTime_ = TimeUtils::GetCurSec();
79 }
80 if (afterSleepTime_ - lastSystemTonePlaybackTime_ >= systemTonePlaybackSleepTime_) {
81 HandleToSystemTonePlaybackEvent();
82 lastSystemTonePlaybackTime_ = TimeUtils::GetCurSec();
83 }
84 }
85 }
86
StartTimeThread()87 void MediaMonitorPolicy::StartTimeThread()
88 {
89 timeThread_ = std::make_unique<std::thread>(&MediaMonitorPolicy::TimeFunc, this);
90 pthread_setname_np(timeThread_->native_handle(), "DFXTiming");
91 }
92
StopTimeThread()93 void MediaMonitorPolicy::StopTimeThread()
94 {
95 startThread_.store(false, std::memory_order_release);
96 }
97
WriteEvent(EventId eventId,std::shared_ptr<EventBean> & bean)98 void MediaMonitorPolicy::WriteEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
99 {
100 MEDIA_LOG_D("Write event");
101 if (bean == nullptr) {
102 MEDIA_LOG_E("eventBean is nullptr");
103 return;
104 }
105 if (bean->GetEventType() == BEHAVIOR_EVENT) {
106 WriteBehaviorEvent(eventId, bean);
107 } else if (bean->GetEventType() == FAULT_EVENT) {
108 WriteFaultEvent(eventId, bean);
109 } else {
110 WriteAggregationEvent(eventId, bean);
111 }
112 }
113
WriteBehaviorEvent(EventId eventId,std::shared_ptr<EventBean> & bean)114 void MediaMonitorPolicy::WriteBehaviorEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
115 {
116 MEDIA_LOG_D("Write behavior event");
117 BundleInfo bundleInfo = {};
118 switch (eventId) {
119 case DEVICE_CHANGE:
120 mediaEventBaseWriter_.WriteDeviceChange(bean);
121 break;
122 case HEADSET_CHANGE:
123 mediaEventBaseWriter_.WriteHeasetChange(bean);
124 break;
125 case STREAM_CHANGE:
126 setAppNameToEventVector("UID", bean);
127 mediaEventBaseWriter_.WriteStreamChange(bean);
128 break;
129 case VOLUME_CHANGE:
130 mediaEventBaseWriter_.WriteVolumeChange(bean);
131 break;
132 case AUDIO_ROUTE_CHANGE:
133 mediaEventBaseWriter_.WriteAudioRouteChange(bean);
134 break;
135 case AUDIO_PIPE_CHANGE:
136 setAppNameToEventVector("CLIENT_UID", bean);
137 mediaEventBaseWriter_.WriteAudioPipeChange(bean);
138 break;
139 case AUDIO_FOCUS_MIGRATE:
140 setAppNameToEventVector("CLIENT_UID", bean);
141 mediaEventBaseWriter_.WriteFocusMigrate(bean);
142 break;
143 case SET_FORCE_USE_AUDIO_DEVICE:
144 setAppNameToEventVector("CLIENT_UID", bean);
145 mediaEventBaseWriter_.WriteSetForceDevice(bean);
146 break;
147 case BACKGROUND_SILENT_PLAYBACK:
148 bundleInfo = GetBundleInfo(bean->GetIntValue("CLIENT_UID"));
149 bean->Add("APP_NAME", bundleInfo.appName);
150 bean->Add("APP_VERSION_CODE", bundleInfo.versionCode);
151 mediaEventBaseWriter_.WriteBGSilentPlayback(bean);
152 break;
153 case STREAM_STANDBY:
154 mediaEventBaseWriter_.WriteStreamStandby(bean);
155 break;
156 case AI_VOICE_NOISE_SUPPRESSION:
157 mediaEventBaseWriter_.WriteNoiseSuppression(bean);
158 break;
159 default:
160 WriteBehaviorEventExpansion(eventId, bean);
161 break;
162 }
163 }
164
WriteBehaviorEventExpansion(EventId eventId,std::shared_ptr<EventBean> & bean)165 void MediaMonitorPolicy::WriteBehaviorEventExpansion(EventId eventId, std::shared_ptr<EventBean> &bean)
166 {
167 MEDIA_LOG_D("Write behavior event expansion");
168 BundleInfo bundleInfo = {};
169 switch (eventId) {
170 case VOLUME_SUBSCRIBE:
171 bundleInfo = GetBundleInfo(bean->GetIntValue("CLIENT_UID"));
172 bean->Add("SUBSCRIBE_KEY", bundleInfo.subscrbeKey);
173 bean->Add("SUBSCRIBE_RESULT", bundleInfo.subscrbeResult);
174 mediaEventBaseWriter_.WriteVolumeSubscribe(bean);
175 break;
176 case SMARTPA_STATUS:
177 mediaEventBaseWriter_.WriteSmartPAStatus(bean);
178 break;
179 case EXCLUDE_OUTPUT_DEVICE:
180 setAppNameToEventVector("CLIENT_UID", bean);
181 mediaEventBaseWriter_.WriteExcludeOutputDevice(bean);
182 break;
183 case SYSTEM_TONE_PLAYBACK:
184 systemTonePlayEventVector_.push_back(bean);
185 TriggerSystemTonePlaybackEvent(bean);
186 break;
187 default:
188 break;
189 }
190 }
191
TriggerSystemTonePlaybackEvent(std::shared_ptr<EventBean> & bean)192 void MediaMonitorPolicy::TriggerSystemTonePlaybackEvent(std::shared_ptr<EventBean> &bean)
193 {
194 MEDIA_LOG_D("Trigger system tone playback event . ");
195
196 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
197 systemTonePlayerCount_++;
198 MEDIA_LOG_I("systemTonePlayerCount_ . = %{public}d", systemTonePlayerCount_);
199 if (systemTonePlayerCount_ >= MAX_PLAY_COUNT) {
200 auto dfxResult = std::make_unique<DfxSystemTonePlaybackResult>();
201 CollectDataToDfxResult(dfxResult.get());
202
203 mediaEventBaseWriter_.WriteSystemTonePlayback(std::move(dfxResult));
204 systemTonePlayerCount_ = 0;
205 lastSystemTonePlaybackTime_ = TimeUtils::GetCurSec();
206 systemTonePlayEventVector_.clear();
207 }
208 }
209
TriggerSystemTonePlaybackTimeEvent(std::shared_ptr<EventBean> & bean)210 void MediaMonitorPolicy::TriggerSystemTonePlaybackTimeEvent(std::shared_ptr<EventBean> &bean)
211 {
212 MEDIA_LOG_D("TriggerSystemTonePlaybackTimeEvent . ");
213 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
214 auto dfxResult = std::make_unique<DfxSystemTonePlaybackResult>();
215 CollectDataToDfxResult(dfxResult.get());
216 mediaEventBaseWriter_.WriteSystemTonePlayback(std::move(dfxResult));
217 systemTonePlayerCount_ = 0;
218 systemTonePlayEventVector_.clear();
219 }
220
CollectDataToDfxResult(DfxSystemTonePlaybackResult * result)221 void MediaMonitorPolicy::CollectDataToDfxResult(DfxSystemTonePlaybackResult *result)
222 {
223 MEDIA_LOG_D("Collect data to dfx result .");
224 for (const auto& bean : systemTonePlayEventVector_) {
225 if (bean == nullptr || result == nullptr) {
226 MEDIA_LOG_E("The incoming data is invalid or data is nullptr.");
227 return;
228 }
229 result->timeStamp.push_back(bean->GetUint64Value("TIME_STAMP"));
230 result->systemSoundType.push_back(bean->GetIntValue("SYSTEM_SOUND_TYPE"));
231 result->clientUid.push_back(bean->GetIntValue("CLIENT_UID"));
232 result->deviceType.push_back(bean->GetIntValue("DEVICE_TYPE"));
233 result->errorCode.push_back(bean->GetIntValue("ERROR_CODE"));
234 result->errorReason.push_back(bean->GetStringValue("ERROR_REASON"));
235 result->muteState.push_back(bean->GetIntValue("MUTE_STATE"));
236 result->muteHaptics.push_back(bean->GetIntValue("MUTE_HAPTICS"));
237 result->ringMode.push_back(bean->GetIntValue("RING_MODE"));
238 result->streamType.push_back(bean->GetIntValue("STREAM_TYPE"));
239 result->vibrationState.push_back(bean->GetIntValue("VIBRATION_STATE"));
240 result->volumeLevel.push_back(bean->GetIntValue("VOLUME_LEVEL"));
241 }
242 }
243
setAppNameToEventVector(const std::string key,std::shared_ptr<EventBean> & bean)244 void MediaMonitorPolicy::setAppNameToEventVector(const std::string key, std::shared_ptr<EventBean> &bean)
245 {
246 BundleInfo bundleInfo = GetBundleInfo(bean->GetIntValue(key));
247 bean->Add("APP_NAME", bundleInfo.appName);
248 }
249
SetBundleNameToEvent(const std::string key,std::shared_ptr<EventBean> & bean,const std::string & bundleNameKey)250 void MediaMonitorPolicy::SetBundleNameToEvent(const std::string key, std::shared_ptr<EventBean> &bean,
251 const std::string &bundleNameKey)
252 {
253 FALSE_RETURN_MSG(bean != nullptr, "eventBean is nullptr");
254 BundleInfo bundleInfo = GetBundleInfo(bean->GetIntValue(key));
255 bean->Add(bundleNameKey, bundleInfo.appName);
256 }
257
GetBundleInfo(int32_t appUid)258 BundleInfo MediaMonitorPolicy::GetBundleInfo(int32_t appUid)
259 {
260 auto cachedBundleInfo = cachedBundleInfoMap_.find(appUid);
261 if (cachedBundleInfo != cachedBundleInfoMap_.end()) {
262 return cachedBundleInfo->second;
263 }
264 MediaMonitorWrapper mediaMonitorWrapper;
265 BundleInfo bundleInfo;
266 bundleInfo.appName = "uid:" + std::to_string(appUid); // if no name found, use uid as default
267 MediaMonitorErr err = mediaMonitorWrapper.GetBundleInfo(appUid, &bundleInfo);
268 if (err != MediaMonitorErr::SUCCESS) {
269 return bundleInfo;
270 }
271 cachedBundleInfoMap_.insert(std::make_pair(appUid, bundleInfo));
272 return bundleInfo;
273 }
274
WriteFaultEvent(EventId eventId,std::shared_ptr<EventBean> & bean)275 void MediaMonitorPolicy::WriteFaultEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
276 {
277 MEDIA_LOG_D("Write fault event");
278 BundleInfo bundleInfo;
279 switch (eventId) {
280 case LOAD_CONFIG_ERROR:
281 mediaEventBaseWriter_.WriteLoadConfigError(bean);
282 break;
283 case AUDIO_SERVICE_STARTUP_ERROR:
284 mediaEventBaseWriter_.WriteAudioStartupError(bean);
285 break;
286 case LOAD_EFFECT_ENGINE_ERROR:
287 mediaEventBaseWriter_.WriteLoadEffectEngineError(bean);
288 break;
289 case DB_ACCESS_EXCEPTION:
290 mediaEventBaseWriter_.WriteDbAccessException(bean);
291 break;
292 case DEVICE_CHANGE_EXCEPTION:
293 mediaEventBaseWriter_.WriteDeviceChangeException(bean);
294 break;
295 case APP_WRITE_MUTE:
296 bundleInfo = GetBundleInfo(bean->GetIntValue("UID"));
297 bean->Add("APP_BUNDLE_NAME", bundleInfo.appName);
298 MEDIA_LOG_I("Handle mute event of app:" PUBLIC_LOG_S, bundleInfo.appName.c_str());
299 mediaEventBaseWriter_.WriteAppWriteMute(bean);
300 break;
301 case HDI_EXCEPTION:
302 mediaEventBaseWriter_.WriteHdiException(bean);
303 break;
304 case JANK_PLAYBACK:
305 // update bundle name
306 bundleInfo = GetBundleInfo(bean->GetIntValue("UID"));
307 bean->Add("APP_NAME", bundleInfo.appName);
308 MEDIA_LOG_I("Handle jank event of app:" PUBLIC_LOG_S, bundleInfo.appName.c_str());
309 mediaEventBaseWriter_.WriteJankPlaybackError(bean);
310 break;
311 case RECORD_ERROR:
312 SetBundleNameToEvent("INCOMING_UID", bean, "INCOMING_PKG");
313 SetBundleNameToEvent("ACTIVE_UID", bean, "ACTIVE_PKG");
314 mediaEventBaseWriter_.WriteAudioRecordError(bean);
315 break;
316 default:
317 break;
318 }
319 }
320
WriteAggregationEvent(EventId eventId,std::shared_ptr<EventBean> & bean)321 void MediaMonitorPolicy::WriteAggregationEvent(EventId eventId, std::shared_ptr<EventBean> &bean)
322 {
323 BundleInfo bundleInfo = {};
324 switch (eventId) {
325 case AUDIO_STREAM_EXHAUSTED_STATS:
326 bundleInfo = GetBundleInfo(bean->GetIntValue("CLIENT_UID"));
327 bean->Add("DUBIOUS_APP", bundleInfo.appName);
328 mediaEventBaseWriter_.WriteStreamExhastedError(bean);
329 break;
330 case AUDIO_STREAM_CREATE_ERROR_STATS:
331 bundleInfo = GetBundleInfo(bean->GetIntValue("CLIENT_UID"));
332 bean->Add("APP_NAME", bundleInfo.appName);
333 bean->Add("APP_VERSION_CODE", bundleInfo.versionCode);
334 mediaEventBaseWriter_.WriteStreamCreateError(bean);
335 break;
336 case BACKGROUND_SILENT_PLAYBACK:
337 bundleInfo = GetBundleInfo(bean->GetIntValue("CLIENT_UID"));
338 bean->Add("APP_NAME", bundleInfo.appName);
339 bean->Add("APP_VERSION_CODE", bundleInfo.versionCode);
340 mediaEventBaseWriter_.WriteBackgoundSilentPlayback(bean);
341 break;
342 case STREAM_UTILIZATION_STATS:
343 // update bundle name
344 bundleInfo = GetBundleInfo(bean->GetIntValue("UID"));
345 bean->UpdateStringMap("APP_NAME", bundleInfo.appName);
346 mediaEventBaseWriter_.WriteStreamStatistic(bean);
347 break;
348 case STREAM_PROPERTY_STATS:
349 mediaEventBaseWriter_.WriteStreamPropertyStatistic(bean);
350 break;
351 case AUDIO_DEVICE_UTILIZATION_STATS:
352 mediaEventBaseWriter_.WriteDeviceStatistic(bean);
353 break;
354 case BT_UTILIZATION_STATS:
355 mediaEventBaseWriter_.WriteBtUsageStatistic(bean);
356 break;
357 case PERFORMANCE_UNDER_OVERRUN_STATS:
358 bundleInfo = GetBundleInfo(bean->GetIntValue("CLIENT_UID"));
359 bean->Add("APP_NAME", bundleInfo.appName);
360 mediaEventBaseWriter_.WriteUnderrunStatistic(bean);
361 break;
362 case PLAYBACK_VOLUME_STATS:
363 mediaEventBaseWriter_.WritePlaybackVolume(bean);
364 break;
365 case MUTED_CAPTURE_STATS:
366 mediaEventBaseWriter_.WriteMutedCapture(bean);
367 break;
368 default:
369 WriteAggregationEventExpansion(eventId, bean);
370 break;
371 }
372 }
373
WriteAggregationEventExpansion(EventId eventId,std::shared_ptr<EventBean> & bean)374 void MediaMonitorPolicy::WriteAggregationEventExpansion(EventId eventId, std::shared_ptr<EventBean> &bean)
375 {
376 switch (eventId) {
377 case STREAM_OCCUPANCY:
378 SetBundleNameToEvent("UID", bean, "PKGNAME");
379 mediaEventBaseWriter_.WriteStreamOccupancy(bean);
380 break;
381 case ADD_REMOVE_CUSTOMIZED_TONE:
382 mediaEventBaseWriter_.WriteCustomizedToneChange(bean);
383 break;
384 default:
385 break;
386 }
387 }
388
HandDeviceUsageToEventVector(std::shared_ptr<EventBean> & deviceUsage)389 void MediaMonitorPolicy::HandDeviceUsageToEventVector(std::shared_ptr<EventBean> &deviceUsage)
390 {
391 MEDIA_LOG_I("Handle device usage to event vector");
392 if (deviceUsage == nullptr) {
393 MEDIA_LOG_E("MediaMonitorPolicy HandDeviceUsageToEventVector deviceUsage is nullpr");
394 return;
395 }
396 bool isInEventMap = false;
397 auto isExist = [&deviceUsage](const std::shared_ptr<EventBean> &eventBean) {
398 if (eventBean->GetEventId() == AUDIO_DEVICE_UTILIZATION_STATS &&
399 deviceUsage->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
400 deviceUsage->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
401 deviceUsage->GetIntValue("DEVICE_TYPE") == eventBean->GetIntValue("DEVICE_TYPE")) {
402 MEDIA_LOG_D("Find the existing device usage");
403 return true;
404 }
405 return false;
406 };
407 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
408 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
409 if (it != eventVector_.end()) {
410 uint64_t duration = (*it)->GetUint64Value("DURATION") + deviceUsage->GetUint64Value("DURATION");
411 (*it)->UpdateUint64Map("DURATION", duration);
412 isInEventMap = true;
413 }
414
415 if (!isInEventMap) {
416 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
417 EventId::AUDIO_DEVICE_UTILIZATION_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
418 eventBean->Add("STREAM_TYPE", deviceUsage->GetIntValue("STREAM_TYPE"));
419 eventBean->Add("DEVICE_TYPE", deviceUsage->GetIntValue("DEVICE_TYPE"));
420 eventBean->Add("IS_PLAYBACK", deviceUsage->GetIntValue("IS_PLAYBACK"));
421 eventBean->Add("DURATION", deviceUsage->GetUint64Value("DURATION"));
422 AddToEventVector(eventBean);
423 }
424 }
425
HandBtUsageToEventVector(std::shared_ptr<EventBean> & btUsage)426 void MediaMonitorPolicy::HandBtUsageToEventVector(std::shared_ptr<EventBean> &btUsage)
427 {
428 MEDIA_LOG_I("Handle bt usage to event vector");
429 if (btUsage == nullptr) {
430 MEDIA_LOG_I("MediaMonitorPolicy HandBtUsageToEventVector btUsage is nullpr");
431 return;
432 }
433 bool isInEventMap = false;
434 auto isExist = [&btUsage](const std::shared_ptr<EventBean> &eventBean) {
435 if (eventBean->GetEventId() == BT_UTILIZATION_STATS &&
436 btUsage->GetIntValue("BT_TYPE") == eventBean->GetIntValue("BT_TYPE") &&
437 btUsage->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
438 btUsage->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK")) {
439 MEDIA_LOG_I("Find the existing bt device usage");
440 return true;
441 }
442 return false;
443 };
444 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
445 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
446 if (it != eventVector_.end()) {
447 uint64_t duration = (*it)->GetUint64Value("DURATION") + btUsage->GetUint64Value("DURATION");
448 (*it)->UpdateUint64Map("DURATION", duration);
449 isInEventMap = true;
450 }
451
452 if (!isInEventMap) {
453 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
454 EventId::BT_UTILIZATION_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
455 eventBean->Add("BT_TYPE", btUsage->GetIntValue("BT_TYPE"));
456 eventBean->Add("IS_PLAYBACK", btUsage->GetIntValue("IS_PLAYBACK"));
457 eventBean->Add("STREAM_TYPE", btUsage->GetIntValue("STREAM_TYPE"));
458 eventBean->Add("DURATION", btUsage->GetUint64Value("DURATION"));
459 AddToEventVector(eventBean);
460 }
461 }
462
HandStreamUsageToEventVector(std::shared_ptr<EventBean> & streamUsage)463 void MediaMonitorPolicy::HandStreamUsageToEventVector(std::shared_ptr<EventBean> &streamUsage)
464 {
465 MEDIA_LOG_I("Handle stream usage to event vector");
466 if (streamUsage == nullptr) {
467 MEDIA_LOG_E("MediaMonitorPolicy HandStreamUsageToEventVector streamUsage is nullpr");
468 return;
469 }
470 bool isInEventMap = false;
471 auto isExist = [&streamUsage](const std::shared_ptr<EventBean> &eventBean) {
472 if (eventBean->GetEventId() == STREAM_UTILIZATION_STATS &&
473 streamUsage->GetIntValue("PIPE_TYPE") == eventBean->GetIntValue("PIPE_TYPE") &&
474 streamUsage->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
475 streamUsage->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
476 streamUsage->GetStringValue("APP_NAME") == eventBean->GetStringValue("APP_NAME") &&
477 streamUsage->GetIntValue("SAMPLE_RATE") == eventBean->GetIntValue("SAMPLE_RATE")) {
478 MEDIA_LOG_I("Find the existing stream usage");
479 return true;
480 }
481 return false;
482 };
483 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
484 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
485 if (it != eventVector_.end()) {
486 uint64_t duration = (*it)->GetUint64Value("DURATION") + streamUsage->GetUint64Value("DURATION");
487 (*it)->UpdateUint64Map("DURATION", duration);
488 isInEventMap = true;
489 }
490 if (!isInEventMap) {
491 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
492 EventId::STREAM_UTILIZATION_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
493 eventBean->Add("PIPE_TYPE", streamUsage->GetIntValue("PIPE_TYPE"));
494 eventBean->Add("UID", streamUsage->GetIntValue("UID"));
495 eventBean->Add("IS_PLAYBACK", streamUsage->GetIntValue("IS_PLAYBACK"));
496 eventBean->Add("STREAM_TYPE", streamUsage->GetIntValue("STREAM_TYPE"));
497 eventBean->Add("SAMPLE_RATE", streamUsage->GetIntValue("SAMPLE_RATE"));
498 eventBean->Add("APP_NAME", streamUsage->GetStringValue("APP_NAME"));
499 eventBean->Add("EFFECT_CHAIN", streamUsage->GetIntValue("EFFECT_CHAIN"));
500 eventBean->Add("DURATION", streamUsage->GetUint64Value("DURATION"));
501 AddToEventVector(eventBean);
502 }
503 }
504
HandStreamPropertyToEventVector(std::shared_ptr<EventBean> & streamProperty)505 void MediaMonitorPolicy::HandStreamPropertyToEventVector(std::shared_ptr<EventBean> &streamProperty)
506 {
507 MEDIA_LOG_I("Handle stream property to event vector");
508 if (streamProperty == nullptr) {
509 MEDIA_LOG_E("MediaMonitorPolicy HandStreamPropertyToEventVector streamProperty is nullptr");
510 return;
511 }
512 bool isInEventMap = false;
513 auto isExist = [&streamProperty](const std::shared_ptr<EventBean> &eventBean) {
514 if (eventBean->GetEventId() == STREAM_UTILIZATION_STATS &&
515 streamProperty->GetIntValue("UID") == eventBean->GetIntValue("UID") &&
516 streamProperty->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
517 streamProperty->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
518 streamProperty->GetStringValue("APP_NAME") == eventBean->GetStringValue("APP_NAME") &&
519 streamProperty->GetIntValue("CHANNEL_LAYOUT") ==
520 static_cast<int64_t>(eventBean->GetUint64Value("CHANNEL_LAYOUT")) &&
521 streamProperty->GetIntValue("ENCODING_TYPE") == eventBean->GetIntValue("ENCODING_TYPE")) {
522 MEDIA_LOG_I("Find the existing stream property");
523 return true;
524 }
525 return false;
526 };
527 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
528 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
529 if (it != eventVector_.end()) {
530 uint64_t duration = (*it)->GetUint64Value("DURATION") + streamProperty->GetUint64Value("DURATION");
531 (*it)->UpdateUint64Map("DURATION", duration);
532 isInEventMap = true;
533 }
534
535 if (!isInEventMap) {
536 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
537 EventId::STREAM_PROPERTY_STATS, EventType::DURATION_AGGREGATION_EVENT);
538
539 eventBean->Add("IS_PLAYBACK", streamProperty->GetIntValue("IS_PLAYBACK"));
540 eventBean->Add("STREAM_TYPE", streamProperty->GetIntValue("STREAM_TYPE"));
541 eventBean->Add("APP_NAME", streamProperty->GetStringValue("APP_NAME"));
542 eventBean->Add("ENCODING_TYPE", streamProperty->GetIntValue("ENCODING_TYPE"));
543 eventBean->Add("CHANNEL_LAYOUT", streamProperty->GetUint64Value("CHANNEL_LAYOUT"));
544 eventBean->Add("DURATION", streamProperty->GetUint64Value("DURATION"));
545 AddToEventVector(eventBean);
546 }
547 }
548
HandleVolumeToEventVector(std::shared_ptr<EventBean> & bean)549 void MediaMonitorPolicy::HandleVolumeToEventVector(std::shared_ptr<EventBean> &bean)
550 {
551 MEDIA_LOG_I("Handle volume to event vector");
552 if (bean == nullptr) {
553 MEDIA_LOG_E("MediaMonitorPolicy HandleVolumeToEventVector bean is nullpr");
554 return;
555 }
556 bool isInEventMap = false;
557 auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
558 if (eventBean->GetEventId() == PLAYBACK_VOLUME_STATS &&
559 bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
560 bean->GetIntValue("LEVEL") == eventBean->GetIntValue("LEVEL") &&
561 bean->GetIntValue("DEVICE_TYPE") == eventBean->GetIntValue("DEVICE_TYPE")) {
562 MEDIA_LOG_D("Find the existing volume usage");
563 return true;
564 }
565 return false;
566 };
567
568 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
569 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
570 if (it != eventVector_.end()) {
571 uint64_t duration = (*it)->GetUint64Value("DURATION") + bean->GetUint64Value("DURATION");
572 (*it)->UpdateUint64Map("DURATION", duration);
573 isInEventMap = true;
574 }
575
576 if (!isInEventMap) {
577 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
578 EventId::PLAYBACK_VOLUME_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
579 eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
580 eventBean->Add("LEVEL", bean->GetIntValue("LEVEL"));
581 eventBean->Add("DEVICE_TYPE", bean->GetIntValue("DEVICE_TYPE"));
582 eventBean->Add("DURATION", bean->GetUint64Value("DURATION"));
583 AddToEventVector(eventBean);
584 }
585 }
586
HandleCaptureMutedToEventVector(std::shared_ptr<EventBean> & bean)587 void MediaMonitorPolicy::HandleCaptureMutedToEventVector(std::shared_ptr<EventBean> &bean)
588 {
589 MEDIA_LOG_I("Handle capture muted to event vector");
590 if (bean == nullptr) {
591 MEDIA_LOG_E("MediaMonitorPolicy HandleCaptureMutedToEventVector bean is nullpr");
592 return;
593 }
594 bool isInEventMap = false;
595 auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
596 if (eventBean->GetEventId() == MUTED_CAPTURE_STATS &&
597 bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
598 bean->GetIntValue("DEVICE_TYPE") == eventBean->GetIntValue("DEVICE_TYPE")) {
599 MEDIA_LOG_I("Find the existing capture muted");
600 return true;
601 }
602 return false;
603 };
604 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
605 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
606 if (it != eventVector_.end()) {
607 uint64_t duration = (*it)->GetUint64Value("DURATION") + bean->GetUint64Value("DURATION");
608 (*it)->UpdateUint64Map("DURATION", duration);
609 isInEventMap = true;
610 }
611
612 if (!isInEventMap) {
613 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
614 EventId::MUTED_CAPTURE_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
615 eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
616 eventBean->Add("DEVICE_TYPE", bean->GetIntValue("DEVICE_TYPE"));
617 eventBean->Add("DURATION", bean->GetUint64Value("DURATION"));
618 AddToEventVector(eventBean);
619 }
620 }
621
HandleExhaustedToEventVector(std::shared_ptr<EventBean> & bean)622 void MediaMonitorPolicy::HandleExhaustedToEventVector(std::shared_ptr<EventBean> &bean)
623 {
624 MEDIA_LOG_I("Handle exhausted to event map");
625 int32_t uid = bean->GetIntValue("CLIENT_UID");
626 int32_t appStreamNum = bean->GetIntValue("TIMES");
627 bool isInEventMap = false;
628 auto isExist = [&uid](const std::shared_ptr<EventBean> &eventBean) {
629 if (eventBean->GetEventId() == AUDIO_STREAM_EXHAUSTED_STATS &&
630 uid == eventBean->GetIntValue("CLIENT_UID")) {
631 MEDIA_LOG_I("Find the existing CLIENT_UID");
632 return true;
633 }
634 return false;
635 };
636 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
637 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
638 if (it != eventVector_.end()) {
639 int32_t streamNum = (*it)->GetIntValue("TIMES");
640 if (appStreamNum > streamNum) {
641 (*it)->UpdateIntMap("TIMES", appStreamNum);
642 }
643 isInEventMap = true;
644 }
645 if (!isInEventMap) {
646 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
647 EventId::AUDIO_STREAM_EXHAUSTED_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
648 eventBean->Add("CLIENT_UID", uid);
649 eventBean->Add("TIMES", appStreamNum);
650 AddToEventVector(eventBean);
651 }
652 }
653
HandleCreateErrorToEventVector(std::shared_ptr<EventBean> & bean)654 void MediaMonitorPolicy::HandleCreateErrorToEventVector(std::shared_ptr<EventBean> &bean)
655 {
656 MEDIA_LOG_I("Handle create error to event vector");
657 bool isInEventMap = false;
658 auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
659 if (eventBean->GetEventId() == AUDIO_STREAM_CREATE_ERROR_STATS &&
660 bean->GetIntValue("CLIENT_UID") == eventBean->GetIntValue("CLIENT_UID") &&
661 bean->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
662 bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE") &&
663 bean->GetIntValue("ERROR_CODE") == eventBean->GetIntValue("ERROR_CODE")) {
664 MEDIA_LOG_I("Find the existing create error app");
665 return true;
666 }
667 return false;
668 };
669 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
670 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
671 if (it != eventVector_.end()) {
672 int32_t num = (*it)->GetIntValue("TIMES");
673 (*it)->UpdateIntMap("TIMES", ++num);
674 isInEventMap = true;
675 }
676
677 if (!isInEventMap) {
678 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
679 EventId::AUDIO_STREAM_CREATE_ERROR_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
680 eventBean->Add("CLIENT_UID", bean->GetIntValue("CLIENT_UID"));
681 eventBean->Add("IS_PLAYBACK", bean->GetIntValue("IS_PLAYBACK"));
682 eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
683 eventBean->Add("ERROR_CODE", bean->GetIntValue("ERROR_CODE"));
684 eventBean->Add("TIMES", INITIAL_VALUE);
685 AddToEventVector(eventBean);
686 }
687 }
688
HandleSilentPlaybackToEventVector(std::shared_ptr<EventBean> & bean)689 void MediaMonitorPolicy::HandleSilentPlaybackToEventVector(std::shared_ptr<EventBean> &bean)
690 {
691 MEDIA_LOG_I("Handle silent playback to event vector");
692 bool isInEventMap = false;
693 BundleInfo bundleInfo = GetBundleInfo(bean->GetIntValue("CLIENT_UID"));
694 auto isExist = [&bundleInfo](const std::shared_ptr<EventBean> &eventBean) {
695 if (eventBean->GetEventId() == BACKGROUND_SILENT_PLAYBACK &&
696 bundleInfo.appName == eventBean->GetStringValue("APP_NAME") &&
697 bundleInfo.versionCode == eventBean->GetIntValue("APP_VERSION_CODE")) {
698 MEDIA_LOG_I("Find the existing silent playback app");
699 return true;
700 }
701 return false;
702 };
703 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
704 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
705 if (it != eventVector_.end()) {
706 int32_t num = (*it)->GetIntValue("TIMES");
707 (*it)->UpdateIntMap("TIMES", ++num);
708 isInEventMap = true;
709 }
710 if (!isInEventMap) {
711 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
712 EventId::BACKGROUND_SILENT_PLAYBACK, EventType::FREQUENCY_AGGREGATION_EVENT);
713 eventBean->Add("APP_NAME", bundleInfo.appName);
714 eventBean->Add("APP_VERSION_CODE", bundleInfo.versionCode);
715 eventBean->Add("TIMES", INITIAL_VALUE);
716 AddToEventVector(eventBean);
717 }
718 }
719
HandleUnderrunToEventVector(std::shared_ptr<EventBean> & bean)720 void MediaMonitorPolicy::HandleUnderrunToEventVector(std::shared_ptr<EventBean> &bean)
721 {
722 MEDIA_LOG_I("Handle underrun to event vector");
723 bool isInEventMap = false;
724 auto isExist = [&bean](const std::shared_ptr<EventBean> &eventBean) {
725 if (eventBean->GetEventId() == PERFORMANCE_UNDER_OVERRUN_STATS &&
726 bean->GetIntValue("CLIENT_UID") == eventBean->GetIntValue("CLIENT_UID") &&
727 bean->GetIntValue("IS_PLAYBACK") == eventBean->GetIntValue("IS_PLAYBACK") &&
728 bean->GetIntValue("PIPE_TYPE") == eventBean->GetIntValue("PIPE_TYPE") &&
729 bean->GetIntValue("STREAM_TYPE") == eventBean->GetIntValue("STREAM_TYPE")) {
730 MEDIA_LOG_I("Find the existing underrun app");
731 return true;
732 }
733 return false;
734 };
735 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
736 auto it = std::find_if(eventVector_.begin(), eventVector_.end(), isExist);
737 if (it != eventVector_.end()) {
738 int32_t num = (*it)->GetIntValue("TIMES");
739 (*it)->UpdateIntMap("TIMES", ++num);
740 isInEventMap = true;
741 }
742 if (!isInEventMap) {
743 std::shared_ptr<EventBean> eventBean = std::make_shared<EventBean>(ModuleId::AUDIO,
744 EventId::PERFORMANCE_UNDER_OVERRUN_STATS, EventType::FREQUENCY_AGGREGATION_EVENT);
745 eventBean->Add("CLIENT_UID", bean->GetIntValue("CLIENT_UID"));
746 eventBean->Add("IS_PLAYBACK", bean->GetIntValue("IS_PLAYBACK"));
747 eventBean->Add("PIPE_TYPE", bean->GetIntValue("PIPE_TYPE"));
748 eventBean->Add("STREAM_TYPE", bean->GetIntValue("STREAM_TYPE"));
749 eventBean->Add("TIMES", INITIAL_VALUE);
750 AddToEventVector(eventBean);
751 }
752 }
753
AddToEventVector(std::shared_ptr<EventBean> & bean)754 void MediaMonitorPolicy::AddToEventVector(std::shared_ptr<EventBean> &bean)
755 {
756 MEDIA_LOG_D("Add to event vector");
757 eventVector_.push_back(bean);
758 }
759
WhetherToHiSysEvent()760 void MediaMonitorPolicy::WhetherToHiSysEvent()
761 {
762 MEDIA_LOG_D("eventVector size %{public}zu", eventVector_.size());
763 if (eventVector_.size() >= static_cast<uint32_t>(aggregationFrequency_)) {
764 std::unique_ptr<std::thread> writeEventThread = std::make_unique<std::thread>(
765 &MediaMonitorPolicy::HandleToHiSysEvent, this);
766 pthread_setname_np(writeEventThread->native_handle(), "ToHiSysEvent");
767 writeEventThread->detach();
768 }
769 }
770
HandleToHiSysEvent()771 void MediaMonitorPolicy::HandleToHiSysEvent()
772 {
773 MEDIA_LOG_D("Handle to hiSysEvent");
774 std::vector<std::shared_ptr<EventBean>> eventVector;
775 {
776 std::lock_guard<std::mutex> lockEventVector(eventVectorMutex_);
777 eventVector = eventVector_;
778 eventVector_.clear();
779 }
780 for (auto &desc : eventVector) {
781 if (desc == nullptr) {
782 continue;
783 }
784 WriteEvent(desc->GetEventId(), desc);
785 }
786 }
787
HandleToSystemTonePlaybackEvent()788 void MediaMonitorPolicy::HandleToSystemTonePlaybackEvent()
789 {
790 MEDIA_LOG_D("Handle to systemTone playback Event");
791 for (auto &desc : systemTonePlayEventVector_) {
792 if (desc == nullptr) {
793 continue;
794 }
795 TriggerSystemTonePlaybackTimeEvent(desc);
796 }
797 }
798
WriteInfo(int32_t fd,std::string & dumpString)799 void MediaMonitorPolicy::WriteInfo(int32_t fd, std::string &dumpString)
800 {
801 if (fd != -1) {
802 int32_t remainderSize = aggregationFrequency_ - static_cast<int32_t>(eventVector_.size());
803 int64_t elapsedTime = static_cast<int64_t>((TimeUtils::GetCurSec() - curruntTime_)) / 60;
804 int64_t oneDay = aggregationTime_;
805 dumpString += "Counting of eventVector entries:";
806 dumpString += "\n";
807 dumpString += " The current number of eventVector: " + std::to_string(eventVector_.size());
808 dumpString += "\n";
809 dumpString += " Remaining number of starting refreshes: " + std::to_string(remainderSize);
810 dumpString += "\n";
811 dumpString += "\n";
812 dumpString += "Time Count:";
813 dumpString += "\n";
814 dumpString += " Time elapsed:" + std::to_string(elapsedTime) + "min";
815 dumpString += "\n";
816 dumpString += " Remaining refresh time:" + std::to_string(oneDay - elapsedTime) + "min";
817 dumpString += "\n";
818 dumpString += "\n";
819 }
820 }
821
822 } // namespace MediaMonitor
823 } // namespace Media
824 } // namespace OHOS