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_DIALING_CALL:
87         case AudioEvent::NO_MORE_ALERTING_CALL:
88         case AudioEvent::NO_MORE_HOLDING_CALL:
89             if (DelayedSingleton<CallStateProcessor>::GetInstance()->ShouldStopSoundtone()) {
90                 DelayedSingleton<AudioControlManager>::GetInstance()->
91                     PlayCallEndedTone(CallEndedType::CALL_ENDED_NORMALLY);
92             }
93             currentState_->ProcessEvent(event);
94             break;
95         case AudioEvent::NEW_ACTIVE_CS_CALL:
96         case AudioEvent::NEW_ACTIVE_IMS_CALL:
97         case AudioEvent::NEW_DIALING_CALL:
98         case AudioEvent::NEW_ALERTING_CALL:
99         case AudioEvent::NEW_INCOMING_CALL:
100             currentState_->ProcessEvent(event);
101             break;
102         default:
103             break;
104     }
105 }
106 
ProcessEvent(AudioEvent event)107 bool AudioSceneProcessor::ProcessEvent(AudioEvent event)
108 {
109     reportAudioStateChangeQueue.submit([=]() { ProcessEventInner(event); });
110     return true;
111 }
112 
SwitchState(AudioEvent event)113 bool AudioSceneProcessor::SwitchState(AudioEvent event)
114 {
115     auto itFunc = memberFuncMap_.find(event);
116     if (itFunc != memberFuncMap_.end() && itFunc->second != nullptr) {
117         auto memberFunc = itFunc->second;
118         return memberFunc();
119     }
120     return false;
121 }
122 
SwitchState(CallStateType stateType)123 bool AudioSceneProcessor::SwitchState(CallStateType stateType)
124 {
125     bool result = false;
126     std::lock_guard<std::mutex> lock(mutex_);
127     switch (stateType) {
128         case CallStateType::DIALING_STATE:
129             result = SwitchDialing();
130             break;
131         case CallStateType::ALERTING_STATE:
132             result = SwitchAlerting();
133             break;
134         case CallStateType::INCOMING_STATE:
135             result = SwitchIncoming();
136             break;
137         case CallStateType::CS_CALL_STATE:
138             result = SwitchCS();
139             break;
140         case CallStateType::IMS_CALL_STATE:
141             result = SwitchIMS();
142             break;
143         case CallStateType::HOLDING_STATE:
144             result = SwitchHolding();
145             break;
146         case CallStateType::INACTIVE_STATE:
147             result = SwitchInactive();
148             break;
149         default:
150             break;
151     }
152     TELEPHONY_LOGI("switch call state lock release");
153     return result;
154 }
155 
SwitchDialing()156 bool AudioSceneProcessor::SwitchDialing()
157 {
158     currentState_ = std::make_unique<DialingState>();
159     if (currentState_ == nullptr) {
160         TELEPHONY_LOGE("make_unique DialingState failed");
161         return false;
162     }
163     if (!DelayedSingleton<AudioControlManager>::GetInstance()->PlaySoundtone()) {
164         TELEPHONY_LOGE("PlaySoundtone fail");
165     }
166     DelayedSingleton<AudioControlManager>::GetInstance()->UpdateDeviceTypeForVideoDialing();
167     if (!DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::AUDIO_ACTIVATED)) {
168         TELEPHONY_LOGE("ProcessEvent AUDIO_ACTIVATED failed");
169     }
170     TELEPHONY_LOGI("current call state : dialing state");
171     return true;
172 }
173 
SwitchAlerting()174 bool AudioSceneProcessor::SwitchAlerting()
175 {
176     currentState_ = std::make_unique<AlertingState>();
177     if (currentState_ == nullptr) {
178         TELEPHONY_LOGE("make_unique AlertingState failed");
179         return false;
180     }
181     // play ringback tone while alerting state
182     DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingback();
183     TELEPHONY_LOGI("current call state : alerting state");
184     return true;
185 }
186 
SwitchIncoming()187 bool AudioSceneProcessor::SwitchIncoming()
188 {
189     currentState_ = std::make_unique<IncomingState>();
190     if (currentState_ == nullptr) {
191         TELEPHONY_LOGE("make_unique IncomingState failed");
192         return false;
193     }
194     int32_t state;
195     DelayedSingleton<CallControlManager>::GetInstance()->GetVoIPCallState(state);
196     auto isStartBroadcast = CallVoiceAssistantManager::GetInstance()->IsStartVoiceBroadcast();
197     if (state == (int32_t) CallStateToApp::CALL_STATE_OFFHOOK) {
198         DelayedSingleton<AudioControlManager>::GetInstance()->PlayWaitingTone();
199     } else {
200         if (!isStartBroadcast) {
201             TELEPHONY_LOGI("broadcast switch is close, start play system ring");
202             DelayedSingleton<AudioControlManager>::GetInstance()->StopRingtone();
203             // play ringtone while incoming state
204             DelayedSingleton<AudioControlManager>::GetInstance()->PlayRingtone();
205         }
206         DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::AUDIO_RINGING);
207     }
208     TELEPHONY_LOGI("current call state : incoming state");
209     return true;
210 }
211 
SwitchCS()212 bool AudioSceneProcessor::SwitchCS()
213 {
214     currentState_ = std::make_unique<CSCallState>();
215     if (currentState_ == nullptr) {
216         TELEPHONY_LOGE("make_unique CSCallState failed");
217         return false;
218     }
219     TELEPHONY_LOGI("current call state : cs call state");
220     return true;
221 }
222 
SwitchIMS()223 bool AudioSceneProcessor::SwitchIMS()
224 {
225     currentState_ = std::make_unique<IMSCallState>();
226     if (currentState_ == nullptr) {
227         TELEPHONY_LOGE("make_unique IMSCallState failed");
228         return false;
229     }
230     TELEPHONY_LOGI("current call state : ims call state");
231     return true;
232 }
233 
SwitchHolding()234 bool AudioSceneProcessor::SwitchHolding()
235 {
236     currentState_ = std::make_unique<HoldingState>();
237     if (currentState_ == nullptr) {
238         TELEPHONY_LOGE("make_unique HoldingState failed");
239         return false;
240     }
241     TELEPHONY_LOGI("current call state : holding state");
242     return true;
243 }
244 
SwitchInactive()245 bool AudioSceneProcessor::SwitchInactive()
246 {
247     DelayedSingleton<AudioDeviceManager>::GetInstance()->ProcessEvent(AudioEvent::AUDIO_DEACTIVATED);
248     currentState_ = std::make_unique<InActiveState>();
249     if (currentState_ == nullptr) {
250         TELEPHONY_LOGE("make_unique InActiveState failed");
251         return false;
252     }
253     TELEPHONY_LOGI("current call state : inactive state");
254     return true;
255 }
256 
SwitchOTT()257 bool AudioSceneProcessor::SwitchOTT()
258 {
259     return true;
260 }
261 } // namespace Telephony
262 } // namespace OHOS