• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "avsession_sysevent.h"
17 #include "avsession_log.h"
18 
19 namespace OHOS::AVSession {
20 #ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
21 static const int32_t REPORT_SIZE = 100;
22 
GetInstance()23 AVSessionSysEvent& AVSessionSysEvent::GetInstance()
24 {
25     static AVSessionSysEvent avSessionSysEvent;
26     return avSessionSysEvent;
27 }
28 
AVSessionSysEvent()29 AVSessionSysEvent::AVSessionSysEvent() : optCounts_ {},
30     timer_(nullptr), timerId_(0), lifeCycleInfos_ {}, controllerCommandInfos_ {}, lowQualityInfos_ {}
31 {
32 }
33 
~AVSessionSysEvent()34 AVSessionSysEvent::~AVSessionSysEvent()
35 {
36     SLOGI("AVSessionSysEvent destruct");
37     Unregister();
38 }
39 
AddOperationCount(Operation operation)40 void AVSessionSysEvent::AddOperationCount(Operation operation)
41 {
42     std::lock_guard lockGuard(lock_);
43     auto it = optCounts_.find(operation);
44     if (it == optCounts_.end()) {
45         optCounts_.insert(std::make_pair(operation, 0));
46         it = optCounts_.find(operation);
47     }
48     it->second++;
49 }
50 
Reset()51 void AVSessionSysEvent::Reset()
52 {
53     std::lock_guard lockGuard(lock_);
54     optCounts_.clear();
55     lifeCycleInfos_.clear();
56     controllerCommandInfos_.clear();
57     audioStatuses_.clear();
58     lowQualityInfos_.clear();
59 }
60 
ReportLowQuality()61 void AVSessionSysEvent::ReportLowQuality()
62 {
63     for (auto it = lowQualityInfos_.begin(); it != lowQualityInfos_.end(); it++) {
64         SLOGD("report low quality for %{public}s", it->second.bundleName_.c_str());
65         HiSysWriteStatistic("PLAYING_COMBIND_AVSESSION_STATIS",
66             "BUNDLE_NAME", it->second.bundleName_,
67             "PLAY_DURATION", it->second.playDuration_,
68             "STREAM_USAGE", it->second.streamUsage_,
69             "PLAY_BACK", it->second.isBack_,
70             "AUDIO_ACTIVE", it->second.isAudioActive_,
71             "AVSESSION_META_QUALITY", it->second.metaDataQuality_,
72             "AVSESSION_COMMAND_QUALITY", it->second.cmdQuality_,
73             "AVSESSION_PLAYBACK_STATE", it->second.playbackState_);
74     }
75 }
76 
Regiter()77 void AVSessionSysEvent::Regiter()
78 {
79     CHECK_AND_RETURN(timer_ == nullptr);
80 
81     timer_ = std::make_unique<OHOS::Utils::Timer>("EventStatisticTimer");
82     auto timeCallback = [this]() {
83         std::lock_guard lockGuard(lock_);
84         HiSysWriteStatistic("CONTROL_COMMAND_STATISTICS", "PLAY_COUNT", optCounts_[Operation::OPT_PLAY],
85             "PAUSE_COUNT", optCounts_[Operation::OPT_PAUSE], "STOP_COUNT", optCounts_[Operation::OPT_STOP],
86             "PLAY_NEXT_COUNT", optCounts_[Operation::OPT_PLAY_NEXT],
87             "PLAY_PREVIOUS_COUNT", optCounts_[Operation::OPT_PLAY_PREVIOUS],
88             "FAST_FORWARD_COUNT", optCounts_[Operation::OPT_FAST_FORWARD],
89             "REWIND_COUNT", optCounts_[Operation::OPT_REWIND],
90             "SEEK_COUNT", optCounts_[Operation::OPT_SEEK],
91             "SET_SPEED_COUNT", optCounts_[Operation::OPT_SET_SPEED],
92             "SET_LOOP_MODE_COUNT", optCounts_[Operation::OPT_SET_LOOP_MODE],
93             "SET_TARGET_LOOP_MODE_COUNT", optCounts_[Operation::OPT_SET_TARGET_LOOP_MODE],
94             "TOGGLE_FAVORITE_COUNT", optCounts_[Operation::OPT_TOGGLE_FAVORITE]);
95 
96         for (const auto& it : lifeCycleInfos_) {
97             HiSysWriteStatistic("SESSION_LIFECYCLE_STATISTICS", "BUNDLE_NAME", it.bundleName_,
98                 "APP_STATUS", it.appStatus_, "SESSION_TYPE", it.sessionType_,
99                 "SESSION_LIFE_CYCLE", it.isCreateSession_);
100         }
101 
102         for (const auto& it : controllerCommandInfos_) {
103             HiSysWriteStatistic("CONTROL_COMMAND_STATISTICS", "BUNDLE_NAME", it.bundleName_,
104                 "CONTROLLER_PID", it.controllerPid_, "CMD", it.controllerCmd_,
105                 "DETAILED_MSG", "receiver handle command");
106         }
107 
108         ReportLowQuality();
109 
110         HiSysWriteStatistic("SESSION_LIFECYCLE_STATISTICS",
111             "CREATE_SESSION_COUNT", optCounts_[Operation::OPT_CREATE_SESSION],
112             "DELETE_SESSION_COUNT", optCounts_[Operation::OPT_DELETE_SESSION]);
113 
114         uint32_t allCtrlCmdCount = optCounts_[Operation::OPT_ALL_CTRL_COMMAND];
115         uint32_t allSuccCmdCount = optCounts_[Operation::OPT_SUCCESS_CTRL_COMMAND];
116         if ((allCtrlCmdCount != 0) && (allSuccCmdCount <= allCtrlCmdCount)) {
117             // LCOV_EXCL_START
118             float failedRate = (allCtrlCmdCount - allSuccCmdCount) / (allCtrlCmdCount * MULTIPLE);
119             HiSysWriteStatistic("CONTROL_COMMAND_FAILED_RATE", "ALL_CTRL_COMMAND_COUNT", allCtrlCmdCount,
120                 "ALL_SUCCESS_CTRL_COMMAND", allSuccCmdCount, "COMMAND_FAILED_RATE", failedRate);
121         } else {
122             HiSysWriteStatistic("CONTROL_COMMAND_FAILED_RATE", "ALL_CTRL_COMMAND_COUNT", allCtrlCmdCount,
123                 "ALL_SUCCESS_CTRL_COMMAND", allSuccCmdCount, "COMMAND_FAILED_RATE", 0);
124             // LCOV_EXCL_STOP
125         }
126         Reset();
127         playingStateTriggerCount++;
128         if (playingStateTriggerCount == 24) {
129             ReportPlayingStateAll();
130             playingStateTriggerCount = 0;
131         }
132     };
133     timerId_ = timer_->Register(timeCallback, NOTIFY_TIME_INTERVAL, false);
134     timer_->Setup();
135 }
136 
137 // LCOV_EXCL_START
Unregister()138 void AVSessionSysEvent::Unregister()
139 {
140     if (timer_ != nullptr) {
141         timer_->Shutdown();
142         timer_->Unregister(timerId_);
143         timer_ = nullptr;
144     }
145 }
146 // LCOV_EXCL_STOP
147 
AddLifeCycleInfo(const std::string & bundleName,bool appStatus,const int32_t & sessionType,bool isCreateSession)148 void AVSessionSysEvent::AddLifeCycleInfo(const std::string& bundleName, bool appStatus,
149     const int32_t& sessionType, bool isCreateSession)
150 {
151     AVSessionSysEvent::LifeCycleInfo lifeCycleInfo;
152     lifeCycleInfo.bundleName_ = bundleName;
153     lifeCycleInfo.appStatus_ = appStatus;
154     lifeCycleInfo.sessionType_ = sessionType;
155     lifeCycleInfo.isCreateSession_ = isCreateSession;
156     lifeCycleInfos_.push_back(lifeCycleInfo);
157 }
158 
AddLowQualityInfo(AVSessionSysEvent::BackControlReportInfo & reportInfo)159 void AVSessionSysEvent::AddLowQualityInfo(AVSessionSysEvent::BackControlReportInfo &reportInfo)
160 {
161     if (lowQualityInfos_.find(reportInfo.bundleName_) == lowQualityInfos_.end()) {
162         lowQualityInfos_.insert(std::make_pair(reportInfo.bundleName_, reportInfo));
163     }
164 }
165 
166 // LCOV_EXCL_START
AddControllerCommandInfo(const std::string & bundleName,const pid_t & controllerPid,const int32_t & controllerCmd,const int32_t & sessionType)167 void AVSessionSysEvent::AddControllerCommandInfo(const std::string& bundleName, const pid_t& controllerPid,
168     const int32_t& controllerCmd, const int32_t& sessionType)
169 {
170     AVSessionSysEvent::ControllerCommandInfo controllerCommandInfo;
171     controllerCommandInfo.bundleName_ = bundleName;
172     controllerCommandInfo.controllerPid_ = controllerPid;
173     controllerCommandInfo.controllerCmd_ = controllerCmd;
174     controllerCommandInfos_.push_back(controllerCommandInfo);
175 }
176 
GetAudioStatus(pid_t uid)177 int32_t AVSessionSysEvent::GetAudioStatus(pid_t uid)
178 {
179     std::lock_guard lockGuard(lock_);
180     if (audioStatuses_.find(uid) != audioStatuses_.end()) {
181         return audioStatuses_[uid];
182     }
183     return 0;
184 }
185 // LCOV_EXCL_STOP
186 
SetAudioStatus(pid_t uid,int32_t rendererState)187 void AVSessionSysEvent::SetAudioStatus(pid_t uid, int32_t rendererState)
188 {
189     std::lock_guard lockGuard(lock_);
190     audioStatuses_[uid] = rendererState;
191 }
192 
ReportPlayingState(const std::string & bundleName)193 void AVSessionSysEvent::ReportPlayingState(const std::string& bundleName)
194 {
195     std::lock_guard lockGuard(lock_);
196     CHECK_AND_RETURN(!playingStateInfos_.empty() && playingStateInfos_.find(bundleName) != playingStateInfos_.end());
197     auto playingStateInfo = playingStateInfos_[bundleName].get();
198     if (playingStateInfo != nullptr) {
199         SLOGD("report playing state for %{public}s", playingStateInfo->bundleName_.c_str());
200         HiSysWriteStatistic("PLAYING_AVSESSION_STATS",
201             "APP_NAME", playingStateInfo->bundleName_,
202             "APP_VERSION", playingStateInfo->appVersion_,
203             "AVSESSION_STATE", playingStateInfo->state_,
204             "AVSESSION_STATE_TIMESTAMP", playingStateInfo->stateTime_,
205             "AVSESSION_META_QUALITY", playingStateInfo->metaQuality_,
206             "AVSESSION_META_QUALITY_TIMESTAMP", playingStateInfo->metaQualityTime_,
207             "AVSESSION_COMMAND_QUALITY", playingStateInfo->commandQuality_,
208             "AVSESSION_COMMAND_QUA_TIMESTAMP", playingStateInfo->commandQualityTime_,
209             "AVSESSION_PLAYSTATE", playingStateInfo->playbackState_,
210             "AVSESSION_PLAYSTATE_TIMESTAMP", playingStateInfo->playbackStateTime_,
211             "AVSESSION_CONTROL", playingStateInfo->control_,
212             "AVSESSION_CONTROL_BUNDLE_NAME", playingStateInfo->callerBundleName_,
213             "AVSESSION_CONTROL_TIMESTAMP", playingStateInfo->controlTime_);
214     }
215     playingStateInfos_.erase(bundleName);
216 }
217 
ReportPlayingStateAll()218 void AVSessionSysEvent::ReportPlayingStateAll()
219 {
220     std::lock_guard lockGuard(lock_);
221     std::vector<std::string> keys;
222     for (const auto& it : playingStateInfos_) {
223         keys.push_back(it.first);
224     }
225     for (const auto& key : keys) {
226         ReportPlayingState(key);
227     }
228 }
229 
UTCTimeMilliSeconds()230 static int64_t UTCTimeMilliSeconds()
231 {
232     struct timespec t;
233     constexpr int64_t SEC_TO_MSEC = 1e3;
234     constexpr int64_t MSEC_TO_NSEC = 1e6;
235     clock_gettime(CLOCK_REALTIME, &t);
236     return t.tv_sec * SEC_TO_MSEC + t.tv_nsec / MSEC_TO_NSEC;
237 }
238 
GetPlayingStateInfo(const std::string & bundleName)239 PlayingStateInfo* AVSessionSysEvent::GetPlayingStateInfo(const std::string& bundleName)
240 {
241     std::lock_guard lockGuard(lock_);
242     if (playingStateInfos_.find(bundleName) == playingStateInfos_.end()) {
243         playingStateInfos_.insert({bundleName, std::make_unique<PlayingStateInfo>()});
244         playingStateInfos_[bundleName]->bundleName_ = bundleName;
245     }
246     return playingStateInfos_[bundleName].get();
247 }
248 
UpdateState(const std::string & bundleName,const std::string & appVersion,SessionState state)249 void AVSessionSysEvent::UpdateState(const std::string& bundleName, const std::string& appVersion, SessionState state)
250 {
251     std::lock_guard lockGuard(lock_);
252     PlayingStateInfo* playingStateInfo = GetPlayingStateInfo(bundleName);
253     bool isPlayInfoValid = playingStateInfo != nullptr;
254     CHECK_AND_RETURN(isPlayInfoValid);
255     playingStateInfo->bundleName_ = bundleName;
256     playingStateInfo->appVersion_ = appVersion;
257     playingStateInfo->updateState(state);
258     bool isReportOverSize = playingStateInfo->state_.size() >= REPORT_SIZE;
259     CHECK_AND_RETURN(isReportOverSize);
260     AVSessionSysEvent::GetInstance().ReportPlayingState(bundleName);
261 }
262 
UpdateMetaQuality(const std::string & bundleName,MetadataQuality metaQuality)263 void AVSessionSysEvent::UpdateMetaQuality(const std::string& bundleName, MetadataQuality metaQuality)
264 {
265     std::lock_guard lockGuard(lock_);
266     PlayingStateInfo* playingStateInfo = GetPlayingStateInfo(bundleName);
267     bool isPlayInfoValid = playingStateInfo != nullptr;
268     CHECK_AND_RETURN(isPlayInfoValid);
269     playingStateInfo->updateMetaQuality(metaQuality);
270     bool isReportOverSize = playingStateInfo->metaQuality_.size() >= REPORT_SIZE;
271     CHECK_AND_RETURN(isReportOverSize);
272     AVSessionSysEvent::GetInstance().ReportPlayingState(bundleName);
273 }
274 
UpdateCommandQuality(const std::string & bundleName,uint32_t commandQuality)275 void AVSessionSysEvent::UpdateCommandQuality(const std::string& bundleName, uint32_t commandQuality)
276 {
277     std::lock_guard lockGuard(lock_);
278     PlayingStateInfo* playingStateInfo = GetPlayingStateInfo(bundleName);
279     bool isPlayInfoValid = playingStateInfo != nullptr;
280     CHECK_AND_RETURN(isPlayInfoValid);
281     playingStateInfo->updateCommandQuality(commandQuality);
282     bool isReportOverSize = playingStateInfo->commandQuality_.size() >= REPORT_SIZE;
283     CHECK_AND_RETURN(isReportOverSize);
284     AVSessionSysEvent::GetInstance().ReportPlayingState(bundleName);
285 }
286 
UpdatePlaybackState(const std::string & bundleName,uint8_t playbackState)287 void AVSessionSysEvent::UpdatePlaybackState(const std::string& bundleName, uint8_t playbackState)
288 {
289     std::lock_guard lockGuard(lock_);
290     PlayingStateInfo* playingStateInfo = GetPlayingStateInfo(bundleName);
291     bool isPlayInfoValid = playingStateInfo != nullptr;
292     CHECK_AND_RETURN(isPlayInfoValid);
293     playingStateInfo->updatePlaybackState(playbackState);
294     bool isReportOverSize = playingStateInfo->playbackState_.size() >= REPORT_SIZE;
295     CHECK_AND_RETURN(isReportOverSize);
296     AVSessionSysEvent::GetInstance().ReportPlayingState(bundleName);
297 }
298 
UpdateControl(const std::string & bundleName,uint8_t control,std::string callerBundleName)299 void AVSessionSysEvent::UpdateControl(const std::string& bundleName, uint8_t control, std::string callerBundleName)
300 {
301     std::lock_guard lockGuard(lock_);
302     PlayingStateInfo* playingStateInfo = GetPlayingStateInfo(bundleName);
303     CHECK_AND_RETURN(playingStateInfo != nullptr);
304     playingStateInfo->updateControl(control, callerBundleName);
305     CHECK_AND_RETURN(playingStateInfo->control_.size() >= REPORT_SIZE);
306     AVSessionSysEvent::GetInstance().ReportPlayingState(bundleName);
307 }
308 
updateState(SessionState state)309 void PlayingStateInfo::updateState(SessionState state)
310 {
311     std::lock_guard lockGuard(lock_);
312     if (state != lastState_) {
313         lastState_ = state;
314         state_.push_back(static_cast<uint8_t>(state));
315         stateTime_.push_back(UTCTimeMilliSeconds());
316     }
317 }
318 
updateMetaQuality(MetadataQuality metaQuality)319 void PlayingStateInfo::updateMetaQuality(MetadataQuality metaQuality)
320 {
321     std::lock_guard lockGuard(lock_);
322     metaQuality_.push_back(static_cast<uint8_t>(metaQuality));
323     metaQualityTime_.push_back(UTCTimeMilliSeconds());
324 }
325 
updateCommandQuality(uint32_t commandQuality)326 void PlayingStateInfo::updateCommandQuality(uint32_t commandQuality)
327 {
328     std::lock_guard lockGuard(lock_);
329     if (commandQuality != lastCommandQuality_) {
330         lastCommandQuality_ = commandQuality;
331         commandQuality_.push_back(commandQuality);
332         commandQualityTime_.push_back(UTCTimeMilliSeconds());
333     }
334 }
335 
updatePlaybackState(uint8_t playbackState)336 void PlayingStateInfo::updatePlaybackState(uint8_t playbackState)
337 {
338     std::lock_guard lockGuard(lock_);
339     if (playbackState != lastPlaybackState_) {
340         lastPlaybackState_ = playbackState;
341         playbackState_.push_back(playbackState);
342         playbackStateTime_.push_back(UTCTimeMilliSeconds());
343     }
344 }
345 
updateControl(uint8_t control,std::string callerBundleName)346 void PlayingStateInfo::updateControl(uint8_t control, std::string callerBundleName)
347 {
348     std::lock_guard lockGuard(lock_);
349     if (control != lastControl_) {
350         lastControl_ = control;
351         control_.push_back(control);
352         callerBundleName_.push_back(callerBundleName);
353         controlTime_.push_back(UTCTimeMilliSeconds());
354     }
355 }
356 #endif
357 } // namespace OHOS::AVSession