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