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