• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "ringtone_player_impl.h"
17 
18 #include <sys/stat.h>
19 
20 #include "media_log.h"
21 #include "media_errors.h"
22 
23 using namespace std;
24 using namespace OHOS::AbilityRuntime;
25 
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "RingtonePlayer"};
28 }
29 
30 namespace OHOS {
31 namespace Media {
32 const float HIGH_VOL = 1.0f;
33 const float LOW_VOL = 0.0f;
34 const std::string AUDIO_FORMAT_STR = ".ogg";
35 const std::string HAPTIC_FORMAT_STR = ".json";
36 
RingtonePlayerImpl(const shared_ptr<Context> & context,SystemSoundManagerImpl & sysSoundMgr,RingtoneType type)37 RingtonePlayerImpl::RingtonePlayerImpl(const shared_ptr<Context> &context,
38     SystemSoundManagerImpl &sysSoundMgr, RingtoneType type)
39     : volume_(HIGH_VOL),
40       loop_(false),
41       context_(context),
42       systemSoundMgr_(sysSoundMgr),
43       type_(type)
44 {
45     audioHapticManager_ = AudioHapticManagerFactory::CreateAudioHapticManager();
46     CHECK_AND_RETURN_LOG(audioHapticManager_ != nullptr, "Failed to get audio haptic manager");
47 
48     std::string ringtoneUri = systemSoundMgr_.GetRingtoneUri(context_, type_);
49     InitPlayer(ringtoneUri);
50 }
51 
~RingtonePlayerImpl()52 RingtonePlayerImpl::~RingtonePlayerImpl()
53 {
54     if (player_ != nullptr) {
55         player_->Release();
56         (void)SystemSoundVibrator::StopVibrator();
57         player_ = nullptr;
58         callback_ = nullptr;
59     }
60     if (audioHapticManager_ != nullptr) {
61         audioHapticManager_->UnregisterSource(sourceId_);
62         audioHapticManager_ = nullptr;
63     }
64 }
65 
IsFileExisting(const std::string & fileUri)66 bool RingtonePlayerImpl::IsFileExisting(const std::string &fileUri)
67 {
68     struct stat buffer;
69     return (stat(fileUri.c_str(), &buffer) == 0);
70 }
71 
GetHapticUriForAudioUri(const std::string & audioUri)72 std::string RingtonePlayerImpl::GetHapticUriForAudioUri(const std::string &audioUri)
73 {
74     std::string hapticUri = "";
75     if (audioUri.length() > AUDIO_FORMAT_STR.length() &&
76         audioUri.rfind(AUDIO_FORMAT_STR) == audioUri.length() - AUDIO_FORMAT_STR.length()) {
77         // the end of audio uri is ".ogg"
78         hapticUri = audioUri;
79         hapticUri.replace(hapticUri.rfind(AUDIO_FORMAT_STR), AUDIO_FORMAT_STR.length(), HAPTIC_FORMAT_STR);
80     }
81 
82     if (hapticUri == "" || !IsFileExisting(hapticUri)) {
83         MEDIA_LOGW("Failed to find the vibration json file for audioUri. Use the default json file.");
84         std::string defaultRingtoneUri = systemSoundMgr_.GetDefaultRingtoneUri(RINGTONE_TYPE_SIM_CARD_0);
85         if (defaultRingtoneUri.length() > AUDIO_FORMAT_STR.length() &&
86             defaultRingtoneUri.rfind(AUDIO_FORMAT_STR) == defaultRingtoneUri.length() - AUDIO_FORMAT_STR.length()) {
87             // the end of default ringtone uri is ".ogg"
88             hapticUri = defaultRingtoneUri;
89             hapticUri.replace(hapticUri.rfind(AUDIO_FORMAT_STR), AUDIO_FORMAT_STR.length(), HAPTIC_FORMAT_STR);
90         } else {
91             MEDIA_LOGW("The default ringtone uri is invalid!");
92         }
93     }
94 
95     return hapticUri;
96 }
97 
CreateDataShareHelper(int32_t systemAbilityId)98 static shared_ptr<DataShare::DataShareHelper> CreateDataShareHelper(int32_t systemAbilityId)
99 {
100     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
101     if (saManager == nullptr) {
102         return nullptr;
103     }
104     auto remoteObj = saManager->GetSystemAbility(systemAbilityId);
105     if (remoteObj == nullptr) {
106         return nullptr;
107     }
108     return DataShare::DataShareHelper::Creator(remoteObj, RINGTONE_URI);
109 }
110 
ChangeUri(const std::string & audioUri)111 std::string RingtonePlayerImpl::ChangeUri(const std::string &audioUri)
112 {
113     const std::string FDHEAD = "fd://";
114     std::string ringtoneUri = audioUri;
115     size_t found = audioUri.find(RINGTONE_CUSTOMIZED_BASE_PATH);
116     if (found != std::string::npos) {
117         std::shared_ptr<DataShare::DataShareHelper> dataShareHelper =
118             CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID);
119         CHECK_AND_RETURN_RET_LOG(dataShareHelper != nullptr, audioUri, "Failed to create dataShareHelper.");
120         DataShare::DatashareBusinessError businessError;
121         DataShare::DataSharePredicates queryPredicates;
122         Uri ringtonePathUri(RINGTONE_PATH_URI);
123         vector<string> columns = {{RINGTONE_COLUMN_TONE_ID}, {RINGTONE_COLUMN_DATA}};
124         queryPredicates.EqualTo(RINGTONE_COLUMN_DATA, audioUri);
125         auto resultSet = dataShareHelper->Query(ringtonePathUri, queryPredicates, columns, &businessError);
126         auto results = make_unique<RingtoneFetchResult<RingtoneAsset>>(move(resultSet));
127         unique_ptr<RingtoneAsset> ringtoneAsset = results->GetFirstObject();
128         if (ringtoneAsset != nullptr) {
129             string uriStr = RINGTONE_PATH_URI + RINGTONE_SLASH_CHAR + to_string(ringtoneAsset->GetId());
130             Uri ofUri(uriStr);
131             int32_t fd = dataShareHelper->OpenFile(ofUri, "r");
132             if (fd > 0) {
133                 ringtoneUri = FDHEAD + to_string(fd);
134             }
135         }
136         resultSet == nullptr ? : resultSet->Close();
137         dataShareHelper->Release();
138     }
139     MEDIA_LOGI("RingtonePlayerImpl::ChangeUri ringtoneUri is %{public}s", ringtoneUri.c_str());
140     return ringtoneUri;
141 }
142 
InitPlayer(std::string & audioUri)143 void RingtonePlayerImpl::InitPlayer(std::string &audioUri)
144 {
145     if (sourceId_ != -1) {
146         (void)audioHapticManager_->UnregisterSource(sourceId_);
147         sourceId_ = -1;
148     }
149 
150     AudioHapticPlayerOptions options = {false, false};
151     // Get the haptic file uri according to the audio file uri.
152     std::string hapticUri = GetHapticUriForAudioUri(audioUri);
153     if (hapticUri == "") {
154         MEDIA_LOGW("haptic uri is empty. Play ringtone without vibration");
155         options.muteHaptics = true;
156     }
157 
158     sourceId_ = audioHapticManager_->RegisterSource(ChangeUri(audioUri), hapticUri);
159     CHECK_AND_RETURN_LOG(sourceId_ != -1, "Failed to register source for audio haptic manager");
160     (void)audioHapticManager_->SetAudioLatencyMode(sourceId_, AUDIO_LATENCY_MODE_NORMAL);
161     (void)audioHapticManager_->SetStreamUsage(sourceId_, AudioStandard::StreamUsage::STREAM_USAGE_VOICE_RINGTONE);
162 
163     if (systemSoundMgr_.GetRingerMode() == AudioStandard::AudioRingerMode::RINGER_MODE_SILENT) {
164         options.muteHaptics = true;
165     }
166     player_ = audioHapticManager_->CreatePlayer(sourceId_, options);
167     CHECK_AND_RETURN_LOG(player_ != nullptr, "Failed to create ringtone player instance");
168     int32_t result = player_->Prepare();
169     CHECK_AND_RETURN_LOG(result == MSERR_OK, "Failed to load source for audio haptic manager");
170     configuredUri_ = audioUri;
171 
172     if (callback_ == nullptr) {
173         callback_ = std::make_shared<RingtonePlayerCallback>(*this);
174     }
175     CHECK_AND_RETURN_LOG(callback_ != nullptr, "Failed to create callback object");
176     (void)player_->SetAudioHapticPlayerCallback(callback_);
177     (void)player_->SetVolume(volume_);
178     (void)player_->SetLoop(loop_);
179 
180     ringtoneState_ = STATE_NEW;
181 }
182 
Configure(const float & volume,const bool & loop)183 int32_t RingtonePlayerImpl::Configure(const float &volume, const bool &loop)
184 {
185     MEDIA_LOGI("RingtonePlayerImpl::Configure with volume %{public}f, loop %{public}d", volume, loop);
186     CHECK_AND_RETURN_RET_LOG(volume >= LOW_VOL && volume <= HIGH_VOL,
187         MSERR_INVALID_VAL, "Volume level invalid");
188 
189     std::lock_guard<std::mutex> lock(playerMutex_);
190     CHECK_AND_RETURN_RET_LOG(player_ != nullptr && ringtoneState_ != STATE_INVALID, MSERR_INVALID_VAL, "no player_");
191     volume_ = volume;
192     loop_ = loop;
193     (void)player_->SetVolume(volume_);
194     (void)player_->SetLoop(loop_);
195 
196     return MSERR_OK;
197 }
198 
Start()199 int32_t RingtonePlayerImpl::Start()
200 {
201     MEDIA_LOGI("RingtonePlayerImpl::Start");
202     std::lock_guard<std::mutex> lock(playerMutex_);
203     CHECK_AND_RETURN_RET_LOG(ringtoneState_ != STATE_RUNNING, MSERR_INVALID_OPERATION, "ringtone player is running");
204     CHECK_AND_RETURN_RET_LOG(player_ != nullptr && ringtoneState_ != STATE_INVALID, MSERR_INVALID_VAL, "no player_");
205 
206     std::string ringtoneUri = systemSoundMgr_.GetRingtoneUri(context_, type_);
207     if (ringtoneUri != configuredUri_) {
208         MEDIA_LOGI("Ringtone uri changed. Reload player");
209         InitPlayer(ringtoneUri);
210     }
211     int32_t ret = player_->Start();
212     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_START_FAILED, "Start failed %{public}d", ret);
213     ringtoneState_ = STATE_RUNNING;
214 
215     return MSERR_OK;
216 }
217 
Stop()218 int32_t RingtonePlayerImpl::Stop()
219 {
220     MEDIA_LOGI("RingtonePlayerImpl::Stop");
221     std::lock_guard<std::mutex> lock(playerMutex_);
222     CHECK_AND_RETURN_RET_LOG(ringtoneState_ != STATE_STOPPED, MSERR_INVALID_OPERATION,
223         "ringtone player has been stopped");
224     CHECK_AND_RETURN_RET_LOG(player_ != nullptr && ringtoneState_ != STATE_INVALID, MSERR_INVALID_VAL, "no player_");
225 
226     (void)player_->Stop();
227     ringtoneState_ = STATE_STOPPED;
228 
229     return MSERR_OK;
230 }
231 
Release()232 int32_t RingtonePlayerImpl::Release()
233 {
234     MEDIA_LOGI("RingtonePlayerImpl::Release");
235     std::lock_guard<std::mutex> lock(playerMutex_);
236     CHECK_AND_RETURN_RET_LOG(ringtoneState_ != STATE_RELEASED, MSERR_INVALID_OPERATION,
237         "ringtone player has been released");
238     CHECK_AND_RETURN_RET_LOG(player_ != nullptr && ringtoneState_ != STATE_INVALID, MSERR_INVALID_VAL, "no player_");
239 
240     (void)player_->Release();
241     player_ = nullptr;
242     callback_ = nullptr;
243 
244     if (audioHapticManager_ != nullptr) {
245         audioHapticManager_->UnregisterSource(sourceId_);
246         audioHapticManager_ = nullptr;
247     }
248     sourceId_ = -1;
249     configuredUri_ = "";
250 
251     ringtoneState_ = STATE_RELEASED;
252     return MSERR_OK;
253 }
254 
GetRingtoneState()255 RingtoneState RingtonePlayerImpl::GetRingtoneState()
256 {
257     MEDIA_LOGI("RingtonePlayerImpl::GetRingtoneState");
258     std::lock_guard<std::mutex> lock(playerMutex_);
259     return ringtoneState_;
260 }
261 
GetAudioRendererInfo(AudioStandard::AudioRendererInfo & rendererInfo) const262 int32_t RingtonePlayerImpl::GetAudioRendererInfo(AudioStandard::AudioRendererInfo &rendererInfo) const
263 {
264     MEDIA_LOGI("RingtonePlayerImpl::GetAudioRendererInfo");
265     rendererInfo.contentType = AudioStandard::ContentType::CONTENT_TYPE_UNKNOWN;
266     rendererInfo.streamUsage = AudioStandard::StreamUsage::STREAM_USAGE_RINGTONE;
267     rendererInfo.rendererFlags = 0;
268     return MSERR_OK;
269 }
270 
GetTitle()271 std::string RingtonePlayerImpl::GetTitle()
272 {
273     MEDIA_LOGI("RingtonePlayerImpl::GetTitle");
274     CHECK_AND_RETURN_RET_LOG(configuredUri_ != "", "", "Configured uri is null");
275     return systemSoundMgr_.GetRingtoneTitle(configuredUri_);
276 }
277 
SetRingtonePlayerInterruptCallback(const std::shared_ptr<RingtonePlayerInterruptCallback> & interruptCallback)278 int32_t RingtonePlayerImpl::SetRingtonePlayerInterruptCallback(
279     const std::shared_ptr<RingtonePlayerInterruptCallback> &interruptCallback)
280 {
281     MEDIA_LOGI("RingtonePlayerImpl::SetRingtonePlayerInterruptCallback");
282     std::lock_guard<std::mutex> lock(playerMutex_);
283     interruptCallback_ = interruptCallback;
284     return MSERR_OK;
285 }
286 
NotifyEndofStreamEvent()287 void RingtonePlayerImpl::NotifyEndofStreamEvent()
288 {
289     std::lock_guard<std::mutex> lock(playerMutex_);
290     ringtoneState_ = RingtoneState::STATE_STOPPED;
291 }
292 
NotifyInterruptEvent(const AudioStandard::InterruptEvent & interruptEvent)293 void RingtonePlayerImpl::NotifyInterruptEvent(const AudioStandard::InterruptEvent &interruptEvent)
294 {
295     if (interruptCallback_ != nullptr) {
296         interruptCallback_->OnInterrupt(interruptEvent);
297         MEDIA_LOGI("RingtonePlayerImpl::NotifyInterruptEvent");
298     } else {
299         MEDIA_LOGE("RingtonePlayerImpl::interruptCallback_ is nullptr");
300     }
301 }
302 
303 // Callback class symbols
RingtonePlayerCallback(RingtonePlayerImpl & ringtonePlayerImpl)304 RingtonePlayerCallback::RingtonePlayerCallback(RingtonePlayerImpl &ringtonePlayerImpl)
305     : ringtonePlayerImpl_(ringtonePlayerImpl) {}
306 
OnInterrupt(const AudioStandard::InterruptEvent & interruptEvent)307 void RingtonePlayerCallback::OnInterrupt(const AudioStandard::InterruptEvent &interruptEvent)
308 {
309     MEDIA_LOGI("RingtonePlayerCallback::OnInterrupt: hintTye %{public}d", interruptEvent.hintType);
310     ringtonePlayerImpl_.NotifyInterruptEvent(interruptEvent);
311 }
312 
OnEndOfStream(void)313 void RingtonePlayerCallback::OnEndOfStream(void)
314 {
315     MEDIA_LOGI("RingtonePlayerCallback::OnEndOfStream");
316     ringtonePlayerImpl_.NotifyEndofStreamEvent();
317 }
318 
OnError(int32_t errorCode)319 void RingtonePlayerCallback::OnError(int32_t errorCode)
320 {
321     MEDIA_LOGI("OnError from audio haptic player. errorCode %{public}d", errorCode);
322 }
323 } // namesapce AudioStandard
324 } // namespace OHOS
325