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
18namespace OHOS::AVSession {
19#ifdef ENABLE_AVSESSION_SYSEVENT_CONTROL
20AVSessionSysEvent& AVSessionSysEvent::GetInstance()
21{
22    static AVSessionSysEvent avSessionSysEvent;
23    return avSessionSysEvent;
24}
25
26AVSessionSysEvent::AVSessionSysEvent() : optCounts_ {},
27    timer_(nullptr), timerId_(0), lifeCycleInfos_ {}, controllerCommandInfos_ {}
28{
29}
30
31void AVSessionSysEvent::AddOperationCount(Operation operation)
32{
33    auto it = optCounts_.find(operation);
34    if (it == optCounts_.end()) {
35        optCounts_.insert(std::make_pair(operation, 0));
36        it = optCounts_.find(operation);
37    }
38    it->second++;
39}
40
41void AVSessionSysEvent::Reset()
42{
43    std::lock_guard lockGuard(lock_);
44    optCounts_.clear();
45    lifeCycleInfos_.clear();
46    controllerCommandInfos_.clear();
47    audioStatuses_.clear();
48}
49
50void AVSessionSysEvent::Regiter()
51{
52    if (timer_ != nullptr) {
53        return;
54    }
55
56    timer_ = std::make_unique<OHOS::Utils::Timer>("EventStatisticTimer");
57    auto timeCallback = [this]() {
58        HiSysWriteStatistic("CONTROL_COMMAND_STATISTICS", "PLAY_COUNT", optCounts_[Operation::OPT_PLAY],
59            "PAUSE_COUNT", optCounts_[Operation::OPT_PAUSE], "STOP_COUNT", optCounts_[Operation::OPT_STOP],
60            "PLAY_NEXT_COUNT", optCounts_[Operation::OPT_PLAY_NEXT],
61            "PLAY_PREVIOUS_COUNT", optCounts_[Operation::OPT_PLAY_PREVIOUS],
62            "FAST_FORWARD_COUNT", optCounts_[Operation::OPT_FAST_FORWARD],
63            "REWIND_COUNT", optCounts_[Operation::OPT_REWIND],
64            "SEEK_COUNT", optCounts_[Operation::OPT_SEEK],
65            "SET_SPEED_COUNT", optCounts_[Operation::OPT_SET_SPEED],
66            "SET_LOOP_MODE_COUNT", optCounts_[Operation::OPT_SET_LOOP_MODE],
67            "TOGGLE_FAVORITE_COUNT", optCounts_[Operation::OPT_TOGGLE_FAVORITE]);
68
69        for (const auto& it : lifeCycleInfos_) {
70            HiSysWriteStatistic("SESSION_LIFECYCLE_STATISTICS", "BUNDLE_NAME", it.bundleName_,
71                "APP_STATUS", it.appStatus_, "SESSION_TYPE", it.sessionType_,
72                "SESSION_LIFE_CYCLE", it.isCreateSession_);
73        }
74
75        for (const auto& it : controllerCommandInfos_) {
76            HiSysWriteStatistic("CONTROL_COMMAND_STATISTICS", "BUNDLE_NAME", it.bundleName_,
77                "CONTROLLER_PID", it.controllerPid_, "CMD", it.controllerCmd_,
78                "DETAILED_MSG", "receiver handle command");
79        }
80
81        HiSysWriteStatistic("SESSION_LIFECYCLE_STATISTICS",
82            "CREATE_SESSION_COUNT", optCounts_[Operation::OPT_CREATE_SESSION],
83            "DELETE_SESSION_COUNT", optCounts_[Operation::OPT_DELETE_SESSION]);
84
85        uint32_t allCtrlCmdCount = optCounts_[Operation::OPT_ALL_CTRL_COMMAND];
86        uint32_t allSuccCmdCount = optCounts_[Operation::OPT_SUCCESS_CTRL_COMMAND];
87        if ((allCtrlCmdCount != 0) && (allSuccCmdCount <= allCtrlCmdCount)) {
88            // LCOV_EXCL_START
89            float failedRate = (allCtrlCmdCount - allSuccCmdCount) / (allCtrlCmdCount * MULTIPLE);
90            HiSysWriteStatistic("CONTROL_COMMAND_FAILED_RATE", "ALL_CTRL_COMMAND_COUNT", allCtrlCmdCount,
91                "ALL_SUCCESS_CTRL_COMMAND", allSuccCmdCount, "COMMAND_FAILED_RATE", failedRate);
92        } else {
93            HiSysWriteStatistic("CONTROL_COMMAND_FAILED_RATE", "ALL_CTRL_COMMAND_COUNT", allCtrlCmdCount,
94                "ALL_SUCCESS_CTRL_COMMAND", allSuccCmdCount, "COMMAND_FAILED_RATE", 0);
95            // LCOV_EXCL_STOP
96        }
97        Reset();
98    };
99    timerId_ = timer_->Register(timeCallback, NOTIFY_TIME_INTERVAL, false);
100    timer_->Setup();
101}
102
103// LCOV_EXCL_START
104void AVSessionSysEvent::Unregister()
105{
106    if (timer_ != nullptr) {
107        timer_->Shutdown();
108        timer_->Unregister(timerId_);
109        timer_ = nullptr;
110    }
111}
112// LCOV_EXCL_STOP
113
114void AVSessionSysEvent::AddLifeCycleInfo(const std::string& bundleName, bool appStatus,
115    const int32_t& sessionType, bool isCreateSession)
116{
117    AVSessionSysEvent::LifeCycleInfo lifeCycleInfo;
118    lifeCycleInfo.bundleName_ = bundleName;
119    lifeCycleInfo.appStatus_ = appStatus;
120    lifeCycleInfo.sessionType_ = sessionType;
121    lifeCycleInfo.isCreateSession_ = isCreateSession;
122    lifeCycleInfos_.push_back(lifeCycleInfo);
123}
124
125// LCOV_EXCL_START
126void AVSessionSysEvent::AddControllerCommandInfo(const std::string& bundleName, const pid_t& controllerPid,
127    const int32_t& controllerCmd, const int32_t& sessionType)
128{
129    AVSessionSysEvent::ControllerCommandInfo controllerCommandInfo;
130    controllerCommandInfo.bundleName_ = bundleName;
131    controllerCommandInfo.controllerPid_ = controllerPid;
132    controllerCommandInfo.controllerCmd_ = controllerCmd;
133    controllerCommandInfos_.push_back(controllerCommandInfo);
134}
135
136int32_t AVSessionSysEvent::GetAudioStatus(pid_t uid)
137{
138    std::lock_guard lockGuard(lock_);
139    if (audioStatuses_.find(uid) != audioStatuses_.end()) {
140        return audioStatuses_[uid];
141    }
142    return 0;
143}
144// LCOV_EXCL_STOP
145
146void AVSessionSysEvent::SetAudioStatus(pid_t uid, int32_t rendererState)
147{
148    std::lock_guard lockGuard(lock_);
149    audioStatuses_[uid] = rendererState;
150}
151
152#endif
153} // namespace OHOS::AVSession