1 /*
2  * Copyright (C) 2021 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 "call_state_processor.h"
17 
18 #include "audio_control_manager.h"
19 #include "audio_scene_processor.h"
20 #include "call_object_manager.h"
21 #include "telephony_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace Telephony {
CallStateProcessor()25 CallStateProcessor::CallStateProcessor() {}
26 
~CallStateProcessor()27 CallStateProcessor::~CallStateProcessor()
28 {
29     activeCalls_.clear();
30     alertingCalls_.clear();
31     incomingCalls_.clear();
32     holdingCalls_.clear();
33     dialingCalls_.clear();
34 }
35 
AddCall(int32_t callId,TelCallState state)36 void CallStateProcessor::AddCall(int32_t callId, TelCallState state)
37 {
38     std::lock_guard<std::mutex> lock(mutex_);
39     switch (state) {
40         case TelCallState::CALL_STATUS_DIALING:
41             if (dialingCalls_.count(callId) == EMPTY_VALUE) {
42                 TELEPHONY_LOGI("add call , state : dialing");
43                 dialingCalls_.insert(callId);
44             }
45             break;
46         case TelCallState::CALL_STATUS_ALERTING:
47             if (alertingCalls_.count(callId) == EMPTY_VALUE) {
48                 TELEPHONY_LOGI("add call , state : alerting");
49                 alertingCalls_.insert(callId);
50             }
51             break;
52         case TelCallState::CALL_STATUS_WAITING:
53         case TelCallState::CALL_STATUS_INCOMING:
54             if (incomingCalls_.count(callId) == EMPTY_VALUE) {
55                 TELEPHONY_LOGI("add call , state : incoming");
56                 incomingCalls_.insert(callId);
57             }
58             break;
59         case TelCallState::CALL_STATUS_ACTIVE:
60             if (activeCalls_.count(callId) == EMPTY_VALUE) {
61                 TELEPHONY_LOGI("add call , state : active");
62                 activeCalls_.insert(callId);
63             }
64             break;
65         case TelCallState::CALL_STATUS_HOLDING:
66             if (holdingCalls_.count(callId) == EMPTY_VALUE) {
67                 TELEPHONY_LOGI("add call , state : holding");
68                 holdingCalls_.insert(callId);
69             }
70             break;
71         default:
72             break;
73     }
74 }
75 
DeleteCall(int32_t callId,TelCallState state)76 void CallStateProcessor::DeleteCall(int32_t callId, TelCallState state)
77 {
78     std::lock_guard<std::mutex> lock(mutex_);
79     switch (state) {
80         case TelCallState::CALL_STATUS_DIALING:
81             if (dialingCalls_.count(callId) > EMPTY_VALUE) {
82                 TELEPHONY_LOGI("erase call , state : dialing");
83                 dialingCalls_.erase(callId);
84             }
85             break;
86         case TelCallState::CALL_STATUS_ALERTING:
87             if (alertingCalls_.count(callId) > EMPTY_VALUE) {
88                 TELEPHONY_LOGI("erase call , state : alerting");
89                 alertingCalls_.erase(callId);
90             }
91             break;
92         case TelCallState::CALL_STATUS_WAITING:
93         case TelCallState::CALL_STATUS_INCOMING:
94             if (incomingCalls_.count(callId) > EMPTY_VALUE) {
95                 TELEPHONY_LOGI("erase call , state : incoming");
96                 incomingCalls_.erase(callId);
97             }
98             break;
99         case TelCallState::CALL_STATUS_ACTIVE:
100             if (activeCalls_.count(callId) > EMPTY_VALUE) {
101                 TELEPHONY_LOGI("erase call , state : active");
102                 activeCalls_.erase(callId);
103             }
104             break;
105         case TelCallState::CALL_STATUS_HOLDING:
106             if (holdingCalls_.count(callId) > EMPTY_VALUE) {
107                 TELEPHONY_LOGI("erase call , state : holding");
108                 holdingCalls_.erase(callId);
109             }
110             break;
111         default:
112             break;
113     }
114 }
115 
GetCallNumber(TelCallState state)116 int32_t CallStateProcessor::GetCallNumber(TelCallState state)
117 {
118     std::lock_guard<std::mutex> lock(mutex_);
119     int32_t number = EMPTY_VALUE;
120     switch (state) {
121         case TelCallState::CALL_STATUS_DIALING:
122             number = static_cast<int32_t>(dialingCalls_.size());
123             break;
124         case TelCallState::CALL_STATUS_ALERTING:
125             number = static_cast<int32_t>(alertingCalls_.size());
126             break;
127         case TelCallState::CALL_STATUS_INCOMING:
128             number = static_cast<int32_t>(incomingCalls_.size());
129             break;
130         case TelCallState::CALL_STATUS_ACTIVE:
131             number = static_cast<int32_t>(activeCalls_.size());
132             break;
133         case TelCallState::CALL_STATUS_HOLDING:
134             number = static_cast<int32_t>(holdingCalls_.size());
135             break;
136         default:
137             break;
138     }
139     return number;
140 }
141 
ShouldSwitchState(TelCallState callState)142 bool CallStateProcessor::ShouldSwitchState(TelCallState callState)
143 {
144     std::lock_guard<std::mutex> lock(mutex_);
145     bool shouldSwitch = false;
146     switch (callState) {
147         case TelCallState::CALL_STATUS_DIALING:
148             shouldSwitch = (dialingCalls_.size() == EXIST_ONLY_ONE_CALL && activeCalls_.empty() &&
149                 incomingCalls_.empty() && alertingCalls_.empty());
150             break;
151         case TelCallState::CALL_STATUS_ALERTING:
152             shouldSwitch = (alertingCalls_.size() == EXIST_ONLY_ONE_CALL && activeCalls_.empty() &&
153                 incomingCalls_.empty() && dialingCalls_.empty());
154             break;
155         case TelCallState::CALL_STATUS_INCOMING:
156             shouldSwitch = (incomingCalls_.size() == EXIST_ONLY_ONE_CALL && activeCalls_.empty() &&
157                 dialingCalls_.empty() && alertingCalls_.empty());
158             break;
159         case TelCallState::CALL_STATUS_ACTIVE:
160             shouldSwitch = (activeCalls_.size() == EXIST_ONLY_ONE_CALL);
161             break;
162         default:
163             break;
164     }
165     return shouldSwitch;
166 }
167 
UpdateCurrentCallState()168 bool CallStateProcessor::UpdateCurrentCallState()
169 {
170     std::lock_guard<std::mutex> lock(mutex_);
171     if (activeCalls_.size() > EMPTY_VALUE) {
172         // no need to update call state while active calls exists
173         return false;
174     }
175     AudioEvent event = AudioEvent::UNKNOWN_EVENT;
176     if (holdingCalls_.size() > EMPTY_VALUE) {
177         event = AudioEvent::SWITCH_HOLDING_STATE;
178     } else if (incomingCalls_.size() > EMPTY_VALUE) {
179         event = AudioEvent::SWITCH_INCOMING_STATE;
180     } else if (dialingCalls_.size() > EMPTY_VALUE) {
181         event = AudioEvent::SWITCH_DIALING_STATE;
182     } else if (alertingCalls_.size() > EMPTY_VALUE) {
183         event = AudioEvent::SWITCH_ALERTING_STATE;
184     } else {
185         event = AudioEvent::SWITCH_AUDIO_INACTIVE_STATE;
186     }
187     return DelayedSingleton<AudioSceneProcessor>::GetInstance()->ProcessEvent(event);
188 }
189 
ShouldStopSoundtone()190 bool CallStateProcessor::ShouldStopSoundtone()
191 {
192     std::lock_guard<std::mutex> lock(mutex_);
193     if (activeCalls_.size() > EMPTY_VALUE
194         || (incomingCalls_.size() > EMPTY_VALUE && CallObjectManager::HasIncomingCallCrsType())) {
195         // no need to stop soundtone
196         return false;
197     }
198     if (holdingCalls_.size() == EMPTY_VALUE && dialingCalls_.size() == EMPTY_VALUE &&
199         alertingCalls_.size() == EMPTY_VALUE) {
200         return true;
201     }
202     return false;
203 }
204 
GetAudioForegroundLiveCall()205 int32_t CallStateProcessor::GetAudioForegroundLiveCall()
206 {
207     std::lock_guard<std::mutex> lock(mutex_);
208     int32_t callId = INVALID_CALLID;
209     if (activeCalls_.size() > EMPTY_VALUE) {
210         callId = *activeCalls_.begin();
211     } else if (dialingCalls_.size() > EMPTY_VALUE) {
212         callId = *dialingCalls_.begin();
213     } else if (alertingCalls_.size() > EMPTY_VALUE) {
214         callId = *alertingCalls_.begin();
215     } else if (incomingCalls_.size() > EMPTY_VALUE) {
216         callId = *incomingCalls_.begin();
217     } else if (holdingCalls_.size() > EMPTY_VALUE) {
218         callId = *holdingCalls_.begin();
219     }
220     return callId;
221 }
222 
GetCurrentActiveCall()223 int32_t CallStateProcessor::GetCurrentActiveCall()
224 {
225     std::lock_guard<std::mutex> lock(mutex_);
226     if (activeCalls_.size() > EMPTY_VALUE) {
227         return (*activeCalls_.begin());
228     }
229     return INVALID_CALLID;
230 }
231 } // namespace Telephony
232 } // namespace OHOS