• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioConcurrencyService"
17 #endif
18 
19 #include "audio_utils.h"
20 #include "audio_stream_collector.h"
21 #include "audio_concurrency_service.h"
22 #include "audio_concurrency_state_listener_proxy.h"
23 
24 namespace OHOS {
25 namespace AudioStandard {
Init()26 void AudioConcurrencyService::Init()
27 {
28     AUDIO_INFO_LOG("AudioConcurrencyService Init");
29     std::unique_ptr<AudioConcurrencyParser> parser = std::make_unique<AudioConcurrencyParser>();
30     CHECK_AND_RETURN_LOG(parser != nullptr, "Create audioConcurrency parser failed!");
31     CHECK_AND_RETURN_LOG(!parser->LoadConfig(concurrencyCfgMap_), "Load audioConcurrency cfgMap failed!");
32 }
33 
DispatchConcurrencyEventWithSessionId(uint32_t sessionID)34 void AudioConcurrencyService::DispatchConcurrencyEventWithSessionId(uint32_t sessionID)
35 {
36     CHECK_AND_RETURN_LOG(sessionID >= MIN_STREAMID && sessionID <= MAX_STREAMID,
37         "EntryPoint Taint Mark:arg sessionID: %{public}u is tained", sessionID);
38     std::lock_guard<std::mutex> lock(cbMapMutex_);
39     AUDIO_DEBUG_LOG("DispatchConcurrencyEventWithSessionId %{public}d", sessionID);
40     CHECK_AND_RETURN_LOG(concurrencyClients_.find(sessionID) != concurrencyClients_.end(),
41         "session %{public}u not exist", sessionID);
42     concurrencyClients_[sessionID]->OnConcedeStream();
43 }
44 
AudioConcurrencyDeathRecipient(const std::shared_ptr<AudioConcurrencyService> & service,uint32_t sessionID)45 AudioConcurrencyService::AudioConcurrencyDeathRecipient::AudioConcurrencyDeathRecipient(
46     const std::shared_ptr<AudioConcurrencyService> &service, uint32_t sessionID)
47     : service_(service), sessionID_(sessionID)
48 {
49 }
50 
OnRemoteDied(const wptr<IRemoteObject> & remote)51 void AudioConcurrencyService::AudioConcurrencyDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
52 {
53     std::shared_ptr<AudioConcurrencyService> service = service_.lock();
54     if (service != nullptr) {
55         service->UnsetAudioConcurrencyCallback(sessionID_);
56     }
57 }
58 
AudioConcurrencyClient(const std::shared_ptr<AudioConcurrencyCallback> & callback,const sptr<IRemoteObject> & object,const sptr<AudioConcurrencyDeathRecipient> & deathRecipient,uint32_t sessionID)59 AudioConcurrencyService::AudioConcurrencyClient::AudioConcurrencyClient(
60     const std::shared_ptr<AudioConcurrencyCallback> &callback, const sptr<IRemoteObject> &object,
61     const sptr<AudioConcurrencyDeathRecipient> &deathRecipient, uint32_t sessionID)
62     : callback_(callback), object_(object), deathRecipient_(deathRecipient), sessionID_(sessionID)
63 {
64     AUDIO_DEBUG_LOG("callback ctor, sessionID %{public}u", sessionID_);
65 }
66 
~AudioConcurrencyClient()67 AudioConcurrencyService::AudioConcurrencyClient::~AudioConcurrencyClient()
68 {
69     AUDIO_DEBUG_LOG("callback dtor, sessionID %{public}u", sessionID_);
70     if (object_ != nullptr) {
71         object_->RemoveDeathRecipient(deathRecipient_);
72     }
73 }
74 
SetAudioConcurrencyCallback(const uint32_t sessionID,const sptr<IRemoteObject> & object)75 int32_t AudioConcurrencyService::SetAudioConcurrencyCallback(const uint32_t sessionID,
76     const sptr<IRemoteObject> &object)
77 {
78     std::lock_guard<std::mutex> lock(cbMapMutex_);
79 
80     // maybe add check session id validation here
81 
82     CHECK_AND_RETURN_RET_LOG(object != nullptr, ERR_INVALID_PARAM, "AudioConcurrencytCb object is nullptr");
83 
84     sptr<IStandardConcurrencyStateListener> listener = iface_cast<IStandardConcurrencyStateListener>(object);
85     CHECK_AND_RETURN_RET_LOG(listener != nullptr, ERR_INVALID_PARAM, "AudioConcurrencytCb obj cast failed");
86 
87     std::shared_ptr<AudioConcurrencyCallback> callback = std::make_shared<AudioConcurrencyListenerCallback>(listener);
88     CHECK_AND_RETURN_RET_LOG(callback != nullptr, ERR_INVALID_PARAM, "AudioConcurrencyService create cb failed");
89 
90     if (concurrencyClients_.find(sessionID) == concurrencyClients_.end()) {
91         sptr<AudioConcurrencyDeathRecipient> deathRecipient = new
92             AudioConcurrencyDeathRecipient(shared_from_this(), sessionID);
93         object->AddDeathRecipient(deathRecipient);
94         std::shared_ptr<AudioConcurrencyClient> client =
95             std::make_shared<AudioConcurrencyClient>(callback, object, deathRecipient, sessionID);
96         concurrencyClients_[sessionID] = client;
97     } else {
98         AUDIO_ERR_LOG("session %{public}u already exist", sessionID);
99         return ERR_INVALID_PARAM;
100     }
101 
102     return SUCCESS;
103 }
104 
UnsetAudioConcurrencyCallback(const uint32_t sessionID)105 int32_t AudioConcurrencyService::UnsetAudioConcurrencyCallback(const uint32_t sessionID)
106 {
107     std::lock_guard<std::mutex> lock(cbMapMutex_);
108 
109     if (concurrencyClients_.erase(sessionID) == 0) {
110         AUDIO_ERR_LOG("session %{public}u not present", sessionID);
111         return ERR_INVALID_PARAM;
112     }
113     return SUCCESS;
114 }
115 
SetCallbackHandler(std::shared_ptr<AudioPolicyServerHandler> handler)116 void AudioConcurrencyService::SetCallbackHandler(std::shared_ptr<AudioPolicyServerHandler> handler)
117 {
118     handler_ = handler;
119 }
120 
OnConcedeStream()121 void AudioConcurrencyService::AudioConcurrencyClient::OnConcedeStream()
122 {
123     if (callback_ != nullptr) {
124         AudioStreamCollector &streamCollector = AudioStreamCollector::GetAudioStreamCollector();
125         std::vector<std::shared_ptr<AudioCapturerChangeInfo>> capturerChangeInfos;
126         streamCollector.GetCurrentCapturerChangeInfos(capturerChangeInfos);
127         for (auto &capturerChangeInfo : capturerChangeInfos) {
128             uint32_t tmpSessionId = static_cast<uint32_t>(capturerChangeInfo->sessionId);
129             if (tmpSessionId == sessionID_) {
130                 SwitchStreamInfo info = {
131                     sessionID_,
132                     capturerChangeInfo->createrUID,
133                     capturerChangeInfo->clientUID,
134                     capturerChangeInfo->clientPid,
135                     capturerChangeInfo->appTokenId,
136                     capturerChangeInfo->capturerState,
137                 };
138                 SwitchStreamUtil::UpdateSwitchStreamRecord(info, SWITCH_STATE_WAITING);
139                 break;
140             }
141         }
142         callback_->OnConcedeStream();
143     }
144 }
145 
ActivateAudioConcurrency(AudioPipeType incomingPipeType,const std::vector<std::shared_ptr<AudioRendererChangeInfo>> & audioRendererChangeInfos,const std::vector<std::shared_ptr<AudioCapturerChangeInfo>> & audioCapturerChangeInfos)146 int32_t AudioConcurrencyService::ActivateAudioConcurrency(AudioPipeType incomingPipeType,
147     const std::vector<std::shared_ptr<AudioRendererChangeInfo>> &audioRendererChangeInfos,
148     const std::vector<std::shared_ptr<AudioCapturerChangeInfo>> &audioCapturerChangeInfos)
149 {
150     if (concurrencyCfgMap_.empty()) {
151         return SUCCESS;
152     }
153     for (auto it = audioRendererChangeInfos.begin(); it != audioRendererChangeInfos.end(); it++) {
154         if ((*it)->rendererInfo.pipeType == incomingPipeType && (incomingPipeType == PIPE_TYPE_OFFLOAD ||
155             incomingPipeType == PIPE_TYPE_MULTICHANNEL)) {
156             continue;
157         }
158         CHECK_AND_RETURN_RET_LOG(concurrencyCfgMap_[std::make_pair((*it)->rendererInfo.pipeType, incomingPipeType)] !=
159             CONCEDE_INCOMING, ERR_CONCEDE_INCOMING_STREAM, "existing session %{public}d, "
160             "pipe %{public}d, concede incoming pipe %{public}d", (*it)->sessionId, (*it)->rendererInfo.pipeType,
161             incomingPipeType);
162     }
163     for (auto it = audioCapturerChangeInfos.begin(); it != audioCapturerChangeInfos.end(); it++) {
164         CHECK_AND_RETURN_RET_LOG(concurrencyCfgMap_[std::make_pair((*it)->capturerInfo.pipeType, incomingPipeType)] !=
165             CONCEDE_INCOMING, ERR_CONCEDE_INCOMING_STREAM, "existing session %{public}d, "
166             "pipe %{public}d, concede incoming pipe %{public}d", (*it)->sessionId, (*it)->capturerInfo.pipeType,
167             incomingPipeType);
168     }
169     bool concedeIncomingVoipCap = false;
170     for (auto it = audioRendererChangeInfos.begin(); it != audioRendererChangeInfos.end(); it++) {
171         if ((*it)->rendererInfo.pipeType == incomingPipeType && (incomingPipeType == PIPE_TYPE_OFFLOAD ||
172             incomingPipeType == PIPE_TYPE_MULTICHANNEL)) {
173             continue;
174         }
175         ConcurrencyAction action = concurrencyCfgMap_[std::make_pair((*it)->rendererInfo.pipeType, incomingPipeType)];
176         if (action == CONCEDE_EXISTING && handler_ != nullptr) {
177             handler_->SendConcurrencyEventWithSessionIDCallback((*it)->sessionId);
178         }
179     }
180     for (auto it = audioCapturerChangeInfos.begin(); it != audioCapturerChangeInfos.end(); it++) {
181         ConcurrencyAction action = concurrencyCfgMap_[std::make_pair((*it)->capturerInfo.pipeType, incomingPipeType)];
182         if (action == CONCEDE_EXISTING && handler_ != nullptr) {
183             if (incomingPipeType == PIPE_TYPE_CALL_IN && (*it)->capturerInfo.pipeType == PIPE_TYPE_CALL_IN) {
184                 concedeIncomingVoipCap = true;
185             }
186             handler_->SendConcurrencyEventWithSessionIDCallback((*it)->sessionId);
187         }
188     }
189     CHECK_AND_RETURN_RET_LOG(!concedeIncomingVoipCap, ERR_CONCEDE_INCOMING_STREAM,
190         "Existing call in concede incoming call in");
191     return SUCCESS;
192 }
193 } // namespace AudioStandard
194 } // namespace OHOS