• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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