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
17 #include "audio_stream_event_dispatcher.h"
18 #include "i_standard_capturer_state_change_listener.h"
19 #include "i_standard_renderer_state_change_listener.h"
20
21 namespace OHOS {
22 namespace AudioStandard {
AudioStreamEventDispatcher()23 AudioStreamEventDispatcher::AudioStreamEventDispatcher() : activeThread_(0)
24 {
25 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::AudioStreamEventDispatcher()");
26 }
27
~AudioStreamEventDispatcher()28 AudioStreamEventDispatcher::~AudioStreamEventDispatcher()
29 {
30 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::~AudioStreamEventDispatcher()");
31 }
32
addRendererListener(int32_t clientUID,const std::shared_ptr<AudioRendererStateChangeCallback> & callback)33 void AudioStreamEventDispatcher::addRendererListener(int32_t clientUID,
34 const std::shared_ptr<AudioRendererStateChangeCallback> &callback)
35 {
36 std::lock_guard<std::mutex> lock(rendererStateChangeListnerMutex_);
37 rendererCBMap_[clientUID] = callback;
38 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::addRendererListener:client %{public}d added", clientUID);
39 }
40
removeRendererListener(int32_t clientUID)41 void AudioStreamEventDispatcher::removeRendererListener(int32_t clientUID)
42 {
43 std::lock_guard<std::mutex> lock(rendererStateChangeListnerMutex_);
44 if (rendererCBMap_.erase(clientUID)) {
45 AUDIO_INFO_LOG("AudioStreamEventDispatcher::removeRendererListener:client %{public}d done", clientUID);
46 return;
47 }
48 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::removeRendererListener:client %{public}d not present", clientUID);
49 }
50
addCapturerListener(int32_t clientUID,const std::shared_ptr<AudioCapturerStateChangeCallback> & callback)51 void AudioStreamEventDispatcher::addCapturerListener(int32_t clientUID,
52 const std::shared_ptr<AudioCapturerStateChangeCallback> &callback)
53 {
54 std::lock_guard<std::mutex> lock(capturerStateChangeListnerMutex_);
55 capturerCBMap_[clientUID] = callback;
56 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::addCapturerListener:client %{public}d added", clientUID);
57 }
58
removeCapturerListener(int32_t clientUID)59 void AudioStreamEventDispatcher::removeCapturerListener(int32_t clientUID)
60 {
61 std::lock_guard<std::mutex> lock(capturerStateChangeListnerMutex_);
62 if (capturerCBMap_.erase(clientUID)) {
63 AUDIO_INFO_LOG("AudioStreamEventDispatcher::removeCapturerListener:client %{public}d done", clientUID);
64 return;
65 }
66 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::removeCapturerListener:client %{public}d not present", clientUID);
67 }
68
SendRendererInfoEventToDispatcher(AudioMode mode,std::vector<std::unique_ptr<AudioRendererChangeInfo>> & audioRendererChangeInfos)69 void AudioStreamEventDispatcher::SendRendererInfoEventToDispatcher(AudioMode mode,
70 std::vector<std::unique_ptr<AudioRendererChangeInfo>> &audioRendererChangeInfos)
71 {
72 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::SendRendererInfoEventToDispatcher:mode %{public}d ", mode);
73 unique_ptr<StreamStateChangeRequest> streamStateChangeRequest = make_unique<StreamStateChangeRequest>();
74
75 std::vector<std::unique_ptr<AudioRendererChangeInfo>> rendererChangeInfos;
76 for (const auto &changeInfo : audioRendererChangeInfos) {
77 rendererChangeInfos.push_back(std::make_unique<AudioRendererChangeInfo>(*changeInfo));
78 }
79
80 if (!streamStateChangeRequest) {
81 AUDIO_ERR_LOG("AudioStreamEventDispatcher::SendRendererInfoEventToDispatcher:Memory alloc failed!!");
82 return;
83 }
84 streamStateChangeRequest->mode = mode;
85 streamStateChangeRequest->audioRendererChangeInfos = move(rendererChangeInfos);
86 streamStateChangeQueue_.push(move(streamStateChangeRequest));
87 DispatcherEvent();
88 }
89
SendCapturerInfoEventToDispatcher(AudioMode mode,std::vector<std::unique_ptr<AudioCapturerChangeInfo>> & audioCapturerChangeInfos)90 void AudioStreamEventDispatcher::SendCapturerInfoEventToDispatcher(AudioMode mode,
91 std::vector<std::unique_ptr<AudioCapturerChangeInfo>> &audioCapturerChangeInfos)
92 {
93 AUDIO_DEBUG_LOG("AudioStreamEventDispatcher::SendCapturerInfoEventToDispatcher:mode %{public}d ", mode);
94
95 std::vector<std::unique_ptr<AudioCapturerChangeInfo>> capturerChangeInfos;
96 for (const auto &changeInfo : audioCapturerChangeInfos) {
97 capturerChangeInfos.push_back(std::make_unique<AudioCapturerChangeInfo>(*changeInfo));
98 }
99
100 unique_ptr<StreamStateChangeRequest> streamStateChangeRequest = make_unique<StreamStateChangeRequest>();
101 if (!streamStateChangeRequest) {
102 AUDIO_ERR_LOG("AudioStreamEventDispatcher::Memory alloc failed!!");
103 return;
104 }
105 streamStateChangeRequest->mode = mode;
106 streamStateChangeRequest->audioCapturerChangeInfos = move(capturerChangeInfos);
107 streamStateChangeQueue_.push(move(streamStateChangeRequest));
108 DispatcherEvent();
109 }
110
HandleRendererStreamStateChange(const unique_ptr<StreamStateChangeRequest> & streamStateChangeRequest)111 void AudioStreamEventDispatcher::HandleRendererStreamStateChange(
112 const unique_ptr<StreamStateChangeRequest> &streamStateChangeRequest)
113 {
114 std::lock_guard<std::mutex> lock(rendererStateChangeListnerMutex_);
115 for (auto it = rendererCBMap_.begin(); it != rendererCBMap_.end(); ++it) {
116 std::shared_ptr<AudioRendererStateChangeCallback> rendererStateChangeCb = it->second;
117 if (rendererStateChangeCb == nullptr) {
118 AUDIO_ERR_LOG("rendererStateChangeCb : nullptr for client : %{public}d", it->first);
119 it = rendererCBMap_.erase(it);
120 continue;
121 }
122 rendererStateChangeCb->OnRendererStateChange(streamStateChangeRequest->audioRendererChangeInfos);
123 }
124 }
125
HandleCapturerStreamStateChange(const unique_ptr<StreamStateChangeRequest> & streamStateChangeRequest)126 void AudioStreamEventDispatcher::HandleCapturerStreamStateChange(
127 const unique_ptr<StreamStateChangeRequest> &streamStateChangeRequest)
128 {
129 std::lock_guard<std::mutex> lock(capturerStateChangeListnerMutex_);
130 for (auto it = capturerCBMap_.begin(); it != capturerCBMap_.end(); ++it) {
131 std::shared_ptr<AudioCapturerStateChangeCallback> capturerStateChangeCb = it->second;
132 if (capturerStateChangeCb == nullptr) {
133 AUDIO_ERR_LOG("capturerStateChangeCb : nullptr for client : %{public}d", it->first);
134 it = capturerCBMap_.erase(it);
135 continue;
136 }
137 capturerStateChangeCb->OnCapturerStateChange(streamStateChangeRequest->audioCapturerChangeInfos);
138 }
139 }
140
HandleStreamStateChange()141 void AudioStreamEventDispatcher::HandleStreamStateChange()
142 {
143 AUDIO_DEBUG_LOG("HandleStreamStateChange entered");
144 while (!streamStateChangeQueue_.empty()) {
145 std::unique_ptr<StreamStateChangeRequest> streamStateChangeRequest =
146 std::move(streamStateChangeQueue_.front());
147 if (streamStateChangeRequest != nullptr) {
148 if (streamStateChangeRequest->mode == AUDIO_MODE_PLAYBACK) {
149 HandleRendererStreamStateChange(streamStateChangeRequest);
150 } else {
151 HandleCapturerStreamStateChange(streamStateChangeRequest);
152 }
153 }
154 streamStateChangeQueue_.pop();
155 }
156 activeThread_ --;
157 }
158
DispatcherEvent()159 void AudioStreamEventDispatcher::DispatcherEvent()
160 {
161 AUDIO_DEBUG_LOG("DispatcherEvent entered");
162 size_t avlThread = MAX_THREAD - activeThread_;
163 for (size_t i = 0; i < avlThread; i++) {
164 if (!streamStateChangeQueue_.empty() && (activeThread_ < streamStateChangeQueue_.size())) {
165 std::thread(&AudioStreamEventDispatcher::HandleStreamStateChange, this).detach();
166 activeThread_++;
167 }
168 }
169 }
170 } // namespace AudioStandard
171 } // namespace OHOS
172