• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioStreamMonitor"
17 #endif
18 
19 #include "audio_stream_monitor.h"
20 #include "audio_errors.h"
21 #include "audio_renderer_log.h"
22 #include "audio_utils.h"
23 #include "media_monitor_manager.h"
24 
25 namespace OHOS {
26 namespace AudioStandard {
27 namespace {
28 const int32_t CHECK_ALL_RENDER_UID = -1;
29 const int32_t MAX_REGISTER_CALLBACK_NUM = 30;
30 }
31 
GetInstance()32 AudioStreamMonitor& AudioStreamMonitor::GetInstance()
33 {
34     static AudioStreamMonitor monitor;
35     return monitor;
36 }
37 
HasRegistered(const int32_t pid,const int32_t callbackId)38 bool AudioStreamMonitor::HasRegistered(const int32_t pid, const int32_t callbackId)
39 {
40     auto iter = registerInfo_.find(std::make_pair(pid, callbackId));
41     if (iter != registerInfo_.end()) {
42         AUDIO_INFO_LOG("Monitor has registered, pid = %{public}d, callbackId = %{public}d",
43             pid, callbackId);
44         return true;
45     }
46     AUDIO_INFO_LOG("Monitor not register, pid = %{public}d, callbackId = %{public}d", pid, callbackId);
47     return false;
48 }
49 
RegisterAudioRendererDataTransferStateListener(const DataTransferMonitorParam & param,const int32_t pid,const int32_t callbackId)50 int32_t AudioStreamMonitor::RegisterAudioRendererDataTransferStateListener(
51     const DataTransferMonitorParam &param, const int32_t pid, const int32_t callbackId)
52 {
53     std::lock_guard<std::mutex> lock(regStatusMutex_);
54     AUDIO_INFO_LOG("Start register, pid = %{public}d, callbackId = %{public}d", pid, callbackId);
55     if (registerInfo_.size() > MAX_REGISTER_CALLBACK_NUM) {
56         AUDIO_ERR_LOG("Audio stream register num exceed max");
57         return ERR_AUDIO_STREAM_REGISTER_EXCEED_MAX;
58     }
59     if (HasRegistered(pid, callbackId)) {
60         AUDIO_ERR_LOG("Audio stream register repeat");
61         return ERR_AUDIO_STREAM_REGISTER_REPEAT;
62     }
63 
64     std::pair<int32_t, int32_t> pairData = std::make_pair(pid, callbackId);
65     registerInfo_[pairData] = param;
66     AUDIO_INFO_LOG("Register audio stream monitor success");
67     for (auto &item : audioStreamCheckers_) {
68         if (item.second->GetAppUid() == param.clientUID || param.clientUID == CHECK_ALL_RENDER_UID) {
69             AUDIO_INFO_LOG("Find and init checker, sessionId = %{public}u, uid = %{public}d",
70                 item.first, param.clientUID);
71             item.second->InitChecker(param, pid, callbackId);
72         }
73     }
74     return SUCCESS;
75 }
76 
UnregisterAudioRendererDataTransferStateListener(const int32_t pid,const int32_t callbackId)77 int32_t AudioStreamMonitor::UnregisterAudioRendererDataTransferStateListener(
78     const int32_t pid, const int32_t callbackId)
79 {
80     std::lock_guard<std::mutex> lock(regStatusMutex_);
81     AUDIO_INFO_LOG("Start unregister, pid = %{public}d, callbackId = %{public}d", pid, callbackId);
82     for (auto iter = registerInfo_.begin(); iter != registerInfo_.end();) {
83         if (iter->first.first == pid && iter->first.second == callbackId) {
84             AUDIO_INFO_LOG("Unregister callback seccess");
85             iter = registerInfo_.erase(iter);
86         } else {
87             iter++;
88         }
89     }
90     for (auto iter = audioStreamCheckers_.begin(); iter != audioStreamCheckers_.end(); iter++) {
91         iter->second->DeleteCheckerPara(pid, callbackId);
92     }
93     return SUCCESS;
94 }
95 
OnCallback(int32_t pid,int32_t callbackId,const AudioRendererDataTransferStateChangeInfo & info)96 void AudioStreamMonitor::OnCallback(int32_t pid, int32_t callbackId,
97     const AudioRendererDataTransferStateChangeInfo &info)
98 {
99     std::lock_guard<std::mutex> lock(regStatusMutex_);
100     if (audioServer_ == nullptr) {
101         return;
102     }
103     AUDIO_INFO_LOG("pid = %{public}d, callbackid = %{public}d, sessionId = %{public}d, type = %{public}d",
104         pid, callbackId, info.sessionId, info.stateChangeType);
105     audioServer_->OnDataTransferStateChange(pid, callbackId, info);
106 }
107 
OnMuteCallback(const int32_t & pid,const int32_t & callbackId,const int32_t & uid,const uint32_t & sessionId,const bool & isMuted)108 void AudioStreamMonitor::OnMuteCallback(const int32_t &pid, const int32_t &callbackId,
109     const int32_t &uid, const uint32_t &sessionId, const bool &isMuted)
110 {
111     std::lock_guard<std::mutex> lock(regStatusMutex_);
112     if (audioServer_ == nullptr) {
113         return;
114     }
115     AUDIO_INFO_LOG("pid = %{public}d, uid = %{public}d, sessionId = %{public}d, isMuted = %{public}d",
116         pid, uid, sessionId, isMuted);
117     audioServer_->OnMuteStateChange(pid, callbackId, uid, sessionId, isMuted);
118 }
119 
SetAudioServerPtr(DataTransferStateChangeCallbackForMonitor * ptr)120 void AudioStreamMonitor::SetAudioServerPtr(DataTransferStateChangeCallbackForMonitor *ptr)
121 {
122     std::lock_guard<std::mutex> lock(regStatusMutex_);
123     audioServer_ = ptr;
124 }
125 
AddCheckForMonitor(uint32_t sessionId,std::shared_ptr<AudioStreamChecker> & checker)126 void AudioStreamMonitor::AddCheckForMonitor(uint32_t sessionId, std::shared_ptr<AudioStreamChecker> &checker)
127 {
128     std::lock_guard<std::mutex> lock(regStatusMutex_);
129     AUDIO_INFO_LOG("Add checker for monitor, sessionId = %{public}u", sessionId);
130     auto iter = audioStreamCheckers_.find(sessionId);
131     if (iter == audioStreamCheckers_.end()) {
132         audioStreamCheckers_[sessionId] = checker;
133         AUDIO_INFO_LOG("Add checker for monitor success, uid = %{public}d", checker->GetAppUid());
134     }
135     for (auto item : registerInfo_) {
136         if (item.second.clientUID == checker->GetAppUid() || item.second.clientUID == CHECK_ALL_RENDER_UID) {
137             AUDIO_INFO_LOG("Find register, need init checker, uid = %{public}d", item.second.clientUID);
138             checker->InitChecker(item.second, item.first.first, item.first.second);
139         }
140     }
141 }
142 
OnCallbackAppDied(const int32_t pid)143 void AudioStreamMonitor::OnCallbackAppDied(const int32_t pid)
144 {
145     std::lock_guard<std::mutex> lock(regStatusMutex_);
146     AUDIO_INFO_LOG("On callback app died, pid = %{public}d", pid);
147     for (auto iter = registerInfo_.begin(); iter != registerInfo_.end();) {
148         if (iter->first.first == pid) {
149             AUDIO_INFO_LOG("erase registerInfo seccess by pid");
150             iter = registerInfo_.erase(iter);
151         } else {
152             iter++;
153         }
154     }
155     for (auto iter = audioStreamCheckers_.begin(); iter != audioStreamCheckers_.end(); iter++) {
156         iter->second->OnRemoteAppDied(pid);
157     }
158 }
159 
DeleteCheckForMonitor(uint32_t sessionId)160 void AudioStreamMonitor::DeleteCheckForMonitor(uint32_t sessionId)
161 {
162     std::lock_guard<std::mutex> lock(regStatusMutex_);
163     for (auto iter = audioStreamCheckers_.begin(); iter != audioStreamCheckers_.end();) {
164         if (iter->first == sessionId) {
165             AUDIO_INFO_LOG("Find checker and delete, sessionId = %{public}u", sessionId);
166             iter->second->StopCheckStreamThread();
167             iter = audioStreamCheckers_.erase(iter);
168         } else {
169             iter++;
170         }
171     }
172     AUDIO_INFO_LOG("Can not find checker, sessionId = %{public}u", sessionId);
173 }
174 
ReportStreamFreezen(int64_t intervalTime)175 void AudioStreamMonitor::ReportStreamFreezen(int64_t intervalTime)
176 {
177     // To do report
178 }
179 
NotifyAppStateChange(const int32_t uid,bool isBackground)180 void AudioStreamMonitor::NotifyAppStateChange(const int32_t uid, bool isBackground)
181 {
182     std::lock_guard<std::mutex> lock(regStatusMutex_);
183     for (auto iter = audioStreamCheckers_.begin(); iter != audioStreamCheckers_.end();) {
184         if (iter->second->GetAppUid() == uid) {
185             iter->second->UpdateAppState(isBackground);
186         }
187         iter++;
188     }
189 }
190 
UpdateMonitorVolume(const uint32_t & sessionId,const float & volume)191 void AudioStreamMonitor::UpdateMonitorVolume(const uint32_t &sessionId, const float &volume)
192 {
193     std::lock_guard<std::mutex> lock(regStatusMutex_);
194     auto iter = audioStreamCheckers_.find(sessionId);
195     if (iter != audioStreamCheckers_.end()) {
196         iter->second->SetVolume(volume);
197     }
198 }
199 }
200 }