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 "tone.h"
17
18 #include <thread>
19
20 #include "call_control_manager.h"
21 #include "telephony_log_wrapper.h"
22
23 namespace OHOS {
24 namespace Telephony {
25 using AudioPlay = int32_t (AudioPlayer::*)(const std::string &, AudioStandard::AudioStreamType, PlayerType);
26
Tone()27 Tone::Tone() : audioPlayer_(new (std::nothrow) AudioPlayer()) {}
28
Tone(ToneDescriptor tone)29 Tone::Tone(ToneDescriptor tone) : audioPlayer_(new (std::nothrow) AudioPlayer())
30 {
31 currentToneDescriptor_ = tone;
32 }
33
~Tone()34 Tone::~Tone()
35 {
36 if (audioPlayer_ != nullptr) {
37 delete audioPlayer_;
38 audioPlayer_ = nullptr;
39 }
40 }
41
Init()42 void Tone::Init() {}
43
Play()44 int32_t Tone::Play()
45 {
46 if (currentToneDescriptor_ == TONE_UNKNOWN) {
47 TELEPHONY_LOGE("tone descriptor unknown");
48 return CALL_ERR_AUDIO_UNKNOWN_TONE;
49 }
50 if (IsUseTonePlayer(currentToneDescriptor_)) {
51 TELEPHONY_LOGI("currentToneDescriptor = %{public}d", currentToneDescriptor_);
52 if (!InitTonePlayer()) {
53 TELEPHONY_LOGE("InitTonePlayer failed");
54 return TELEPHONY_ERROR;
55 }
56 if (currentToneDescriptor_ == ToneDescriptor::TONE_FINISHED) {
57 if (!tonePlayer_->StartTone()) {
58 return CALL_ERR_AUDIO_TONE_PLAY_FAILED;
59 }
60 return TELEPHONY_SUCCESS;
61 }
62 std::shared_ptr<AudioStandard::TonePlayer> tonePlayerPtr = tonePlayer_;
63 std::thread play([tonePlayerPtr]() {
64 pthread_setname_np(pthread_self(), TONE_PLAY_THREAD);
65 tonePlayerPtr->StartTone();
66 });
67 play.detach();
68 } else {
69 AudioPlay audioPlay = &AudioPlayer::Play;
70 if (audioPlayer_ == nullptr) {
71 TELEPHONY_LOGE("audioPlayer_ is nullptr");
72 return TELEPHONY_ERR_LOCAL_PTR_NULL;
73 }
74 std::thread play(audioPlay, audioPlayer_, GetToneDescriptorPath(currentToneDescriptor_),
75 AudioStandard::AudioStreamType::STREAM_MUSIC, PlayerType::TYPE_TONE);
76 pthread_setname_np(play.native_handle(), TONE_PLAY_THREAD);
77 play.detach();
78 }
79 return TELEPHONY_SUCCESS;
80 }
81
Stop()82 int32_t Tone::Stop()
83 {
84 std::lock_guard<std::mutex> lock(mutex_);
85 if (currentToneDescriptor_ == TONE_UNKNOWN) {
86 TELEPHONY_LOGE("tone descriptor unknown");
87 return CALL_ERR_AUDIO_UNKNOWN_TONE;
88 }
89 if (IsUseTonePlayer(currentToneDescriptor_)) {
90 if (tonePlayer_ != nullptr) {
91 tonePlayer_->StopTone();
92 tonePlayer_->Release();
93 }
94 } else {
95 if (audioPlayer_ == nullptr) {
96 TELEPHONY_LOGE("audioPlayer_ is nullptr");
97 return TELEPHONY_ERR_LOCAL_PTR_NULL;
98 }
99 audioPlayer_->SetStop(PlayerType::TYPE_TONE, true);
100 }
101 return TELEPHONY_SUCCESS;
102 }
103
InitTonePlayer()104 bool Tone::InitTonePlayer()
105 {
106 using namespace OHOS::AudioStandard;
107 if (tonePlayer_ == nullptr) {
108 StreamUsage streamUsage = GetStreamUsageByToneType(currentToneDescriptor_);
109 AudioRendererInfo rendererInfo = {};
110 rendererInfo.contentType = ContentType::CONTENT_TYPE_UNKNOWN;
111 rendererInfo.streamUsage = streamUsage;
112 rendererInfo.rendererFlags = 0;
113 tonePlayer_ = TonePlayer::Create(rendererInfo);
114 if (tonePlayer_ == nullptr) {
115 return false;
116 }
117 ToneType toneType = ConvertToneDescriptorToToneType(currentToneDescriptor_);
118 if (!tonePlayer_->LoadTone(toneType)) {
119 return false;
120 }
121 }
122 return true;
123 }
124
ConvertDigitToTone(char digit)125 ToneDescriptor Tone::ConvertDigitToTone(char digit)
126 {
127 ToneDescriptor dtmf = ToneDescriptor::TONE_UNKNOWN;
128 switch (digit) {
129 case '0':
130 dtmf = ToneDescriptor::TONE_DTMF_CHAR_0;
131 break;
132 case '1':
133 dtmf = ToneDescriptor::TONE_DTMF_CHAR_1;
134 break;
135 case '2':
136 dtmf = ToneDescriptor::TONE_DTMF_CHAR_2;
137 break;
138 case '3':
139 dtmf = ToneDescriptor::TONE_DTMF_CHAR_3;
140 break;
141 case '4':
142 dtmf = ToneDescriptor::TONE_DTMF_CHAR_4;
143 break;
144 case '5':
145 dtmf = ToneDescriptor::TONE_DTMF_CHAR_5;
146 break;
147 case '6':
148 dtmf = ToneDescriptor::TONE_DTMF_CHAR_6;
149 break;
150 case '7':
151 dtmf = ToneDescriptor::TONE_DTMF_CHAR_7;
152 break;
153 case '8':
154 dtmf = ToneDescriptor::TONE_DTMF_CHAR_8;
155 break;
156 case '9':
157 dtmf = ToneDescriptor::TONE_DTMF_CHAR_9;
158 break;
159 case '*':
160 dtmf = ToneDescriptor::TONE_DTMF_CHAR_P;
161 break;
162 case '#':
163 dtmf = ToneDescriptor::TONE_DTMF_CHAR_W;
164 break;
165 default:
166 break;
167 }
168 return dtmf;
169 }
170
ConvertToneDescriptorToToneType(ToneDescriptor tone)171 AudioStandard::ToneType Tone::ConvertToneDescriptorToToneType(ToneDescriptor tone)
172 {
173 using namespace OHOS::AudioStandard;
174 ToneType tonType = ToneType::NUM_TONES;
175 switch (tone) {
176 case ToneDescriptor::TONE_DTMF_CHAR_0:
177 tonType = ToneType::TONE_TYPE_DIAL_0;
178 break;
179 case ToneDescriptor::TONE_DTMF_CHAR_1:
180 tonType = ToneType::TONE_TYPE_DIAL_1;
181 break;
182 case ToneDescriptor::TONE_DTMF_CHAR_2:
183 tonType = ToneType::TONE_TYPE_DIAL_2;
184 break;
185 case ToneDescriptor::TONE_DTMF_CHAR_3:
186 tonType = ToneType::TONE_TYPE_DIAL_3;
187 break;
188 case ToneDescriptor::TONE_DTMF_CHAR_4:
189 tonType = ToneType::TONE_TYPE_DIAL_4;
190 break;
191 case ToneDescriptor::TONE_DTMF_CHAR_5:
192 tonType = ToneType::TONE_TYPE_DIAL_5;
193 break;
194 case ToneDescriptor::TONE_DTMF_CHAR_6:
195 tonType = ToneType::TONE_TYPE_DIAL_6;
196 break;
197 case ToneDescriptor::TONE_DTMF_CHAR_7:
198 tonType = ToneType::TONE_TYPE_DIAL_7;
199 break;
200 case ToneDescriptor::TONE_DTMF_CHAR_8:
201 tonType = ToneType::TONE_TYPE_DIAL_8;
202 break;
203 case ToneDescriptor::TONE_DTMF_CHAR_9:
204 tonType = ToneType::TONE_TYPE_DIAL_9;
205 break;
206 case ToneDescriptor::TONE_DTMF_CHAR_P:
207 tonType = ToneType::TONE_TYPE_DIAL_S;
208 break;
209 case ToneDescriptor::TONE_DTMF_CHAR_W:
210 tonType = ToneType::TONE_TYPE_DIAL_P;
211 break;
212 default:
213 tonType = ConvertCallToneDescriptorToToneType(tone);
214 break;
215 }
216 return tonType;
217 }
218
ConvertCallToneDescriptorToToneType(ToneDescriptor tone)219 AudioStandard::ToneType Tone::ConvertCallToneDescriptorToToneType(ToneDescriptor tone)
220 {
221 using namespace OHOS::AudioStandard;
222 ToneType tonType = ToneType::NUM_TONES;
223 switch (tone) {
224 case ToneDescriptor::TONE_RINGBACK:
225 tonType = ToneType::TONE_TYPE_COMMON_SUPERVISORY_RINGTONE;
226 break;
227 case ToneDescriptor::TONE_WAITING:
228 tonType = ToneType::TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING;
229 break;
230 case ToneDescriptor::TONE_FINISHED:
231 tonType = ToneType::TONE_TYPE_COMMON_PROPRIETARY_PROMPT;
232 break;
233 default:
234 break;
235 }
236 return tonType;
237 }
238
GetStreamUsageByToneType(ToneDescriptor descriptor)239 AudioStandard::StreamUsage Tone::GetStreamUsageByToneType(ToneDescriptor descriptor)
240 {
241 AudioStandard::StreamUsage streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_UNKNOWN;
242 switch (descriptor) {
243 case ToneDescriptor::TONE_DTMF_CHAR_0:
244 case ToneDescriptor::TONE_DTMF_CHAR_1:
245 case ToneDescriptor::TONE_DTMF_CHAR_2:
246 case ToneDescriptor::TONE_DTMF_CHAR_3:
247 case ToneDescriptor::TONE_DTMF_CHAR_4:
248 case ToneDescriptor::TONE_DTMF_CHAR_5:
249 case ToneDescriptor::TONE_DTMF_CHAR_6:
250 case ToneDescriptor::TONE_DTMF_CHAR_7:
251 case ToneDescriptor::TONE_DTMF_CHAR_8:
252 case ToneDescriptor::TONE_DTMF_CHAR_9:
253 case ToneDescriptor::TONE_DTMF_CHAR_P:
254 case ToneDescriptor::TONE_DTMF_CHAR_W:
255 streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_DTMF;
256 break;
257 case ToneDescriptor::TONE_RINGBACK:
258 streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_MODEM_COMMUNICATION;
259 break;
260 case ToneDescriptor::TONE_WAITING:
261 streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_MODEM_COMMUNICATION;
262 int32_t state;
263 DelayedSingleton<CallControlManager>::GetInstance()->GetVoIPCallState(state);
264 if (state == (int32_t)CallStateToApp::CALL_STATE_RINGING ||
265 state == (int32_t)CallStateToApp::CALL_STATE_OFFHOOK ||
266 state == (int32_t)CallStateToApp::CALL_STATE_ANSWERED) {
267 streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_COMMUNICATION;
268 }
269 break;
270 case ToneDescriptor::TONE_FINISHED:
271 streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_VOICE_RINGTONE;
272 break;
273 default:
274 break;
275 }
276 return streamUsage;
277 }
278
IsUseTonePlayer(ToneDescriptor tone)279 bool Tone::IsUseTonePlayer(ToneDescriptor tone)
280 {
281 bool ret = false;
282 switch (tone) {
283 case ToneDescriptor::TONE_DTMF_CHAR_0:
284 case ToneDescriptor::TONE_DTMF_CHAR_1:
285 case ToneDescriptor::TONE_DTMF_CHAR_2:
286 case ToneDescriptor::TONE_DTMF_CHAR_3:
287 case ToneDescriptor::TONE_DTMF_CHAR_4:
288 case ToneDescriptor::TONE_DTMF_CHAR_5:
289 case ToneDescriptor::TONE_DTMF_CHAR_6:
290 case ToneDescriptor::TONE_DTMF_CHAR_7:
291 case ToneDescriptor::TONE_DTMF_CHAR_8:
292 case ToneDescriptor::TONE_DTMF_CHAR_9:
293 case ToneDescriptor::TONE_DTMF_CHAR_P:
294 case ToneDescriptor::TONE_DTMF_CHAR_W:
295 ret = true;
296 break;
297 case ToneDescriptor::TONE_RINGBACK:
298 case ToneDescriptor::TONE_WAITING:
299 case ToneDescriptor::TONE_FINISHED:
300 ret = true;
301 break;
302 default:
303 break;
304 }
305 return ret;
306 }
307
GetToneDescriptorPath(ToneDescriptor tone)308 std::string Tone::GetToneDescriptorPath(ToneDescriptor tone)
309 {
310 #ifdef ABILITY_AUDIO_SUPPORT
311 return DelayedSingleton<AudioProxy>::GetInstance()->GetToneDescriptorPath(tone);
312 #endif
313 return DelayedSingleton<AudioProxy>::GetInstance()->GetDefaultTonePath();
314 }
315
ReleaseRenderer()316 void Tone::ReleaseRenderer()
317 {
318 if (audioPlayer_ == nullptr) {
319 TELEPHONY_LOGE("audioPlayer_ is nullptr");
320 return;
321 }
322 audioPlayer_->ReleaseRenderer();
323 }
324
getCurrentToneType()325 ToneDescriptor Tone::getCurrentToneType()
326 {
327 TELEPHONY_LOGI("currentToneDescriptor_ = %{public}d", currentToneDescriptor_);
328 return currentToneDescriptor_;
329 }
330 } // namespace Telephony
331 } // namespace OHOS
332