1 /*
2  * Copyright (C) 2021-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 "audio_scene_processor.h"
17 
18 #include "dialing_state.h"
19 #include "alerting_state.h"
20 #include "incoming_state.h"
21 #include "call_control_manager.h"
22 #include "cs_call_state.h"
23 #include "holding_state.h"
24 #include "ims_call_state.h"
25 #include "inactive_state.h"
26 #include "audio_control_manager.h"
27 #include "call_state_processor.h"
28 #include "ffrt.h"
29 
30 #include "telephony_log_wrapper.h"
31 #include "call_voice_assistant_manager.h"
32 
33 namespace OHOS {
34 namespace Telephony {
35 namespace {
36     ffrt::queue reportAudioStateChangeQueue { "report_audio_state_change" };
37 }
AudioSceneProcessor()38 AudioSceneProcessor::AudioSceneProcessor()
39     : currentState_(nullptr)
40 {}
41 
~AudioSceneProcessor()42 AudioSceneProcessor::~AudioSceneProcessor() {}
43 
Init()44 int32_t AudioSceneProcessor::Init()
45 {
46     memberFuncMap_[AudioEvent::SWITCH_DIALING_STATE] = [this]() { return SwitchDialing(); };
47     memberFuncMap_[AudioEvent::SWITCH_ALERTING_STATE] = [this]() { return SwitchAlerting(); };
48     memberFuncMap_[AudioEvent::SWITCH_INCOMING_STATE] = [this]() { return SwitchIncoming(); };
49     memberFuncMap_[AudioEvent::SWITCH_CS_CALL_STATE] = [this]() { return SwitchCS(); };
50     memberFuncMap_[AudioEvent::SWITCH_IMS_CALL_STATE] = [this]() { return SwitchIMS(); };
51     memberFuncMap_[AudioEvent::SWITCH_HOLDING_STATE] = [this]() { return SwitchHolding(); };
52     memberFuncMap_[AudioEvent::SWITCH_AUDIO_INACTIVE_STATE] = [this]() { return SwitchInactive(); };
53     currentState_ = std::make_unique<InActiveState>();
54     if (currentState_ == nullptr) {
55         TELEPHONY_LOGE("current call state nullptr");
56         return TELEPHONY_ERR_LOCAL_PTR_NULL;
57     }
58     return TELEPHONY_SUCCESS;
59 }
60 
ProcessEventInner(AudioEvent event)61 void AudioSceneProcessor::ProcessEventInner(AudioEvent event)
62 {
63     if (currentState_ == nullptr) {
64         TELEPHONY_LOGE("current call state nullptr");
65         return;
66     }
67     switch (event) {
68         case AudioEvent::SWITCH_DIALING_STATE:
69         case AudioEvent::SWITCH_ALERTING_STATE:
70         case AudioEvent::SWITCH_INCOMING_STATE:
71         case AudioEvent::SWITCH_CS_CALL_STATE:
72         case AudioEvent::SWITCH_IMS_CALL_STATE:
73         case AudioEvent::SWITCH_HOLDING_STATE:
74         case AudioEvent::SWITCH_AUDIO_INACTIVE_STATE:
75             if (DelayedSingleton<CallStateProcessor>::GetInstance()->ShouldStopSoundtone()) {
76                 DelayedSingleton<AudioControlManager>::GetInstance()->StopSoundtone();
77             }
78             SwitchState(event);
79             break;
80         case AudioEvent::NO_MORE_INCOMING_CALL:
81             DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
82             DelayedSingleton<AudioControlManager>::GetInstance()->StopWaitingTone();
83             currentState_->ProcessEvent(event);
84             break;
85         case AudioEvent::NO_MORE_ACTIVE_CALL:
86         case AudioEvent::NO_MORE_ALERTING_CALL:
87             DelayedSingleton<AudioControlManager>::GetInstance()->StopRingback();
88             if (DelayedSingleton<CallStateProcessor>::GetInstance()->ShouldStopSoundtone()) {
89                 DelayedSingleton<AudioControlManager>::GetInstance()->
90                     PlayCallEndedTone(CallEndedType::CALL_ENDED_NORMALLY);
91             }
92             currentState_->ProcessEvent(event);
93             break;
94         case AudioEvent::NO_MORE_DIALING_CALL:
95         case AudioEvent::NO_MORE_HOLDING_CALL:
96             if (DelayedSingleton<CallStateProcessor>::GetInstance()->ShouldStopSoundtone()) {
97                 DelayedSingleton<AudioControlManager>::GetInstance()->
98                     PlayCallEndedTone(CallEndedType::CALL_ENDED_NORMALLY);
99             }
100             currentState_->ProcessEvent(event);
101             break;
102         case AudioEvent::NEW_ACTIVE_CS_CALL:
103         case AudioEvent::NEW_ACTIVE_IMS_CALL:
104         case AudioEvent::NEW_DIALING_CALL:
105         case AudioEvent::NEW_ALERTING_CALL:
106         case AudioEvent::NEW_INCOMING_CALL:
107             currentState_->ProcessEvent(event);
108             break;
109         default:
110             break;
111     }
112 }
113 
ProcessEvent(AudioEvent event)114 bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
115 {
116     reportAudioStateChangeQueue.submit([=]() { ProcessEventInner(event); });
117     return true;
118 }
119 
SwitchState(AudioEvent event)120 bool AudioSceneProcessor::SwitchState(AudioEvent event)
121 {
122     auto itFunc = memberFuncMap_.find(event);
123     if (itFunc != memberFuncMap_.end() && itFunc->second != nullptr) {
124         auto memberFunc = itFunc->second;
125         return memberFunc();
126     }
127     return false;
128 }
129 
SwitchState(CallStateType stateType)130 bool AudioSceneProcessor::SwitchState(CallStateType stateType)
131 {
132     bool result = false;
133     std::lock_guard<std::mutex> lock(mutex_);
134     switch (stateType) {
135         case CallStateType::DIALING_STATE:
136             result = SwitchDialing();
137             break;
138         case CallStateType::ALERTING_STATE:
139             result = SwitchAlerting();
140             break;
141         case CallStateType::INCOMING_STATE:
142             result = SwitchIncoming();
143             break;
144         case CallStateType::CS_CALL_STATE:
145             result = SwitchCS();
146             break;
147         case CallStateType::IMS_CALL_STATE:
148             result = SwitchIMS();
149             break;
150         case CallStateType::HOLDING_STATE:
151             result = SwitchHolding();
152             break;
153         case CallStateType::INACTIVE_STATE:
154             result = SwitchInactive();
155             break;
156         default:
157             break;
158     }
159     TELEPHONY_LOGI("switch call state lock release");
160     return result;
161 }
162 
SwitchDialing()163 bool AudioSceneProcessor::SwitchDialing()
164 {
165     currentState_ = std::make_unique<DialingState>();
166     if (currentState_ == nullptr) {
167         TELEPHONY_LOGE("make_unique DialingState failed");
168         return false;
169     }
170     if (!DelayedSingleton<AudioControlManager>::GetInstance()->PlaySoundtone()) {
171         TELEPHONY_LOGE("PlaySoundtone fail");
172     }
173     DelayedSingleton<AudioControlManager>::GetInstance()->UpdateDeviceTypeForVideoDialing();
174     if (!DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::AUDIO_ACTIVATED)) {
175         TELEPHONY_LOGE("ProcessEvent AUDIO_ACTIVATED failed");
176     }
177     TELEPHONY_LOGI("current call state : dialing state");
178     return true;
179 }
180 
SwitchAlerting()181 bool AudioSceneProcessor::SwitchAlerting()
182 {
183     currentState_ = std::make_unique<AlertingState>();
184     if (currentState_ == nullptr) {
185         TELEPHONY_LOGE("make_unique AlertingState failed");
186         return false;
187     }
188     // play ringback tone while alerting state
189     DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingback();
190     TELEPHONY_LOGI("current call state : alerting state");
191     return true;
192 }
193 
SwitchIncoming()194 bool AudioSceneProcessor::SwitchIncoming()
195 {
196     currentState_ = std::make_unique<IncomingState>();
197     if (currentState_ == nullptr) {
198         TELEPHONY_LOGE("make_unique IncomingState failed");
199         return false;
200     }
201     int32_t state;
202     DelayedSingleton<CallControlManager>::GetInstance()->GetVoIPCallState(state);
203     auto isStartBroadcast = CallVoiceAssistantManager::GetInstance()->IsStartVoiceBroadcast();
204     if (state == (int32_t) CallStateToApp::CALL_STATE_OFFHOOK) {
205         DelayedSingleton<AudioControlManager>::GetInstance()->PlayWaitingTone();
206     } else {
207         if (!isStartBroadcast) {
208             TELEPHONY_LOGI("broadcast switch is close, start play system ring");
209             DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
210             // play ringtone while incoming state
211             DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingtone();
212         }
213         DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::AUDIO_RINGING);
214     }
215     TELEPHONY_LOGI("current call state : incoming state");
216     return true;
217 }
218 
SwitchCS()219 bool AudioSceneProcessor::SwitchCS()
220 {
221     currentState_ = std::make_unique<CSCallState>();
222     if (currentState_ == nullptr) {
223         TELEPHONY_LOGE("make_unique CSCallState failed");
224         return false;
225     }
226     TELEPHONY_LOGI("current call state : cs call state");
227     return true;
228 }
229 
SwitchIMS()230 bool AudioSceneProcessor::SwitchIMS()
231 {
232     currentState_ = std::make_unique<IMSCallState>();
233     if (currentState_ == nullptr) {
234         TELEPHONY_LOGE("make_unique IMSCallState failed");
235         return false;
236     }
237     TELEPHONY_LOGI("current call state : ims call state");
238     return true;
239 }
240 
SwitchHolding()241 bool AudioSceneProcessor::SwitchHolding()
242 {
243     currentState_ = std::make_unique<HoldingState>();
244     if (currentState_ == nullptr) {
245         TELEPHONY_LOGE("make_unique HoldingState failed");
246         return false;
247     }
248     TELEPHONY_LOGI("current call state : holding state");
249     return true;
250 }
251 
SwitchInactive()252 bool AudioSceneProcessor::SwitchInactive()
253 {
254     DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::AUDIO_DEACTIVATED);
255     currentState_ = std::make_unique<InActiveState>();
256     if (currentState_ == nullptr) {
257         TELEPHONY_LOGE("make_unique InActiveState failed");
258         return false;
259     }
260     TELEPHONY_LOGI("current call state : inactive state");
261     return true;
262 }
263 
SwitchOTT()264 bool AudioSceneProcessor::SwitchOTT()
265 {
266     return true;
267 }
268 } // namespace Telephony
269 } // namespace OHOS