• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "audio_ringtone_manager.h"
17 #include "medialibrary_db_const.h"
18 
19 using namespace std;
20 using namespace OHOS::AbilityRuntime;
21 using namespace OHOS::NativeRdb;
22 using namespace OHOS::Media;
23 
24 namespace OHOS {
25 namespace AudioStandard {
CreateRingtoneManager()26 unique_ptr<IRingtoneSoundManager> RingtoneFactory::CreateRingtoneManager()
27 {
28     unique_ptr<RingtoneSoundManager> soundMgr = make_unique<RingtoneSoundManager>();
29     CHECK_AND_RETURN_RET_LOG(soundMgr != nullptr, nullptr, "Failed to create sound manager object");
30 
31     return soundMgr;
32 }
33 
~RingtoneSoundManager()34 RingtoneSoundManager::~RingtoneSoundManager()
35 {
36     if (abilityHelper_ != nullptr) {
37         abilityHelper_->Release();
38         abilityHelper_ = nullptr;
39     }
40 }
41 
SetSystemRingtoneUri(const shared_ptr<Context> & context,const string & uri,RingtoneType type)42 int32_t RingtoneSoundManager::SetSystemRingtoneUri(const shared_ptr<Context> &context, const string &uri,
43     RingtoneType type)
44 {
45     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s", __func__);
46     CHECK_AND_RETURN_RET_LOG(type >= RINGTONE_TYPE_DEFAULT && type <= RINGTONE_TYPE_MULTISIM,
47                              ERR_INVALID_PARAM, "invalid type");
48 
49     ValuesBucket valuesBucket;
50     valuesBucket.PutString(MEDIA_DATA_DB_RINGTONE_URI, uri);
51     valuesBucket.PutInt(MEDIA_DATA_DB_RINGTONE_TYPE, type);
52 
53     return SetUri(context, valuesBucket, kvstoreOperation[SET_URI_INDEX][RINGTONE_INDEX]);
54 }
55 
SetSystemNotificationUri(const shared_ptr<Context> & context,const string & uri)56 int32_t RingtoneSoundManager::SetSystemNotificationUri(const shared_ptr<Context> &context, const string &uri)
57 {
58     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s", __func__);
59 
60     ValuesBucket valuesBucket;
61     valuesBucket.PutString(MEDIA_DATA_DB_NOTIFICATION_URI, uri);
62 
63     return SetUri(context, valuesBucket, kvstoreOperation[SET_URI_INDEX][NOTIFICATION_INDEX]);
64 }
65 
SetSystemAlarmUri(const shared_ptr<Context> & context,const string & uri)66 int32_t RingtoneSoundManager::SetSystemAlarmUri(const shared_ptr<Context> &context, const string &uri)
67 {
68     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s", __func__);
69 
70     ValuesBucket valuesBucket;
71     valuesBucket.PutString(MEDIA_DATA_DB_ALARM_URI, uri);
72 
73     return SetUri(context, valuesBucket, kvstoreOperation[SET_URI_INDEX][ALARM_INDEX]);
74 }
75 
GetSystemRingtoneUri(const shared_ptr<Context> & context,RingtoneType type)76 string RingtoneSoundManager::GetSystemRingtoneUri(const shared_ptr<Context> &context, RingtoneType type)
77 {
78     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s", __func__);
79     CHECK_AND_RETURN_RET_LOG(type >= RINGTONE_TYPE_DEFAULT && type <= RINGTONE_TYPE_MULTISIM, "", "invalid type");
80 
81     return FetchUri(context, kvstoreOperation[GET_URI_INDEX][RINGTONE_INDEX] + "/" + to_string(type));
82 }
83 
GetSystemNotificationUri(const shared_ptr<Context> & context)84 string RingtoneSoundManager::GetSystemNotificationUri(const shared_ptr<Context> &context)
85 {
86     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s", __func__);
87 
88     return FetchUri(context, kvstoreOperation[GET_URI_INDEX][NOTIFICATION_INDEX]);
89 }
90 
GetSystemAlarmUri(const shared_ptr<Context> & context)91 string RingtoneSoundManager::GetSystemAlarmUri(const shared_ptr<Context> &context)
92 {
93     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s", __func__);
94 
95     return FetchUri(context, kvstoreOperation[GET_URI_INDEX][ALARM_INDEX]);
96 }
97 
SetUri(const shared_ptr<Context> & context,const ValuesBucket & valueBucket,const std::string & operation)98 int32_t RingtoneSoundManager::SetUri(const shared_ptr<Context> &context, const ValuesBucket &valueBucket,
99     const std::string &operation)
100 {
101     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s, operation is %{public}s", __func__, operation.c_str());
102 
103     CreateDataAbilityHelper(context);
104     CHECK_AND_RETURN_RET_LOG(abilityHelper_ != nullptr, ERR_INVALID_PARAM, "Helper is null, failed to set uri");
105 
106     Uri uri(Media::MEDIALIBRARY_DATA_URI + "/" + MEDIA_KVSTOREOPRN + "/" + operation);
107 
108     int32_t result = 0;
109     result = abilityHelper_->Insert(uri, valueBucket);
110     if (result != SUCCESS) {
111         AUDIO_ERR_LOG("RingtoneSoundManager::insert ringtone uri failed");
112     }
113 
114     return result;
115 }
116 
FetchUri(const shared_ptr<Context> & context,const std::string & operation)117 string RingtoneSoundManager::FetchUri(const shared_ptr<Context> &context, const std::string &operation)
118 {
119     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s, operation is %{public}s", __func__, operation.c_str());
120 
121     CreateDataAbilityHelper(context);
122     CHECK_AND_RETURN_RET_LOG(abilityHelper_ != nullptr, "", "Helper is null, failed to retrieve uri");
123 
124     Uri uri(Media::MEDIALIBRARY_DATA_URI + "/" + MEDIA_KVSTOREOPRN + "/" + operation);
125 
126     return abilityHelper_->GetType(uri);
127 }
128 
CreateDataAbilityHelper(const shared_ptr<Context> & context)129 void RingtoneSoundManager::CreateDataAbilityHelper(const shared_ptr<Context> &context)
130 {
131     if (abilityHelper_ == nullptr) {
132         auto contextUri = make_unique<Uri>(Media::MEDIALIBRARY_DATA_URI);
133         CHECK_AND_RETURN_LOG(contextUri != nullptr, "failed to create context uri");
134 
135         abilityHelper_ = AppExecFwk::DataAbilityHelper::Creator(context, move(contextUri));
136         CHECK_AND_RETURN_LOG(abilityHelper_ != nullptr, "Unable to create data ability helper");
137     }
138 }
139 
GetRingtonePlayer(const shared_ptr<Context> & context,RingtoneType type)140 shared_ptr<IRingtonePlayer> RingtoneSoundManager::GetRingtonePlayer(const shared_ptr<Context> &context,
141     RingtoneType type)
142 {
143     AUDIO_INFO_LOG("RingtoneSoundManager::%{public}s, type %{public}d", __func__, type);
144     CHECK_AND_RETURN_RET_LOG(type >= RINGTONE_TYPE_DEFAULT && type <= RINGTONE_TYPE_MULTISIM, nullptr, "invalid type");
145 
146     if (ringtonePlayer_[type] != nullptr && ringtonePlayer_[type]->GetRingtoneState() == STATE_RELEASED) {
147         ringtonePlayer_[type] = nullptr;
148     }
149 
150     if (ringtonePlayer_[type] == nullptr) {
151         ringtonePlayer_[type] = make_shared<RingtonePlayer>(context, *this, type);
152         CHECK_AND_RETURN_RET_LOG(ringtonePlayer_[type] != nullptr, nullptr, "Failed to create ringtone player object");
153     }
154 
155     return ringtonePlayer_[type];
156 }
157 
158 // Player class symbols
RingtonePlayer(const shared_ptr<Context> & context,RingtoneSoundManager & audioMgr,RingtoneType type)159 RingtonePlayer::RingtonePlayer(const shared_ptr<Context> &context, RingtoneSoundManager &audioMgr, RingtoneType type)
160     : volume_(HIGH_VOL), loop_(false), context_(context), audioRingtoneMgr_(audioMgr), type_(type)
161 {
162     InitialisePlayer();
163     (void)Configure(volume_, loop_);
164 }
165 
~RingtonePlayer()166 RingtonePlayer::~RingtonePlayer()
167 {
168     if (player_ != nullptr) {
169         player_->Release();
170         player_ = nullptr;
171         callback_ = nullptr;
172     }
173 }
174 
InitialisePlayer()175 void RingtonePlayer::InitialisePlayer()
176 {
177     player_ = Media::PlayerFactory::CreatePlayer();
178     CHECK_AND_RETURN_LOG(player_ != nullptr, "Failed to create ringtone player instance");
179 
180     callback_ = std::make_shared<RingtonePlayerCallback>(*this);
181     CHECK_AND_RETURN_LOG(callback_ != nullptr, "Failed to create callback object");
182 
183     player_->SetPlayerCallback(callback_);
184     ringtoneState_ = STATE_NEW;
185     configuredUri_ = "";
186 }
187 
PrepareRingtonePlayer(bool isReInitNeeded)188 int32_t RingtonePlayer::PrepareRingtonePlayer(bool isReInitNeeded)
189 {
190     AUDIO_INFO_LOG("RingtonePlayer::%{public}s", __func__);
191     CHECK_AND_RETURN_RET_LOG(player_ != nullptr, ERR_INVALID_PARAM, "Ringtone player instance is null");
192 
193     // fetch uri from kvstore
194     auto kvstoreUri = audioRingtoneMgr_.GetSystemRingtoneUri(context_, type_);
195     CHECK_AND_RETURN_RET_LOG(!kvstoreUri.empty(), ERR_INVALID_PARAM, "Failed to obtain ringtone uri for playing");
196 
197     // If uri is different from from configure uri, reset the player
198     if (kvstoreUri != configuredUri_ || isReInitNeeded) {
199         (void)player_->Reset();
200 
201         auto ret = player_->SetSource(kvstoreUri);
202         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Set source failed %{public}d", ret);
203 
204         ret = player_->PrepareAsync();
205         CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "Prepare failed %{public}d", ret);
206 
207         configuredUri_ = kvstoreUri;
208         ringtoneState_ = STATE_NEW;
209     }
210 
211     return SUCCESS;
212 }
213 
Configure(const float & volume,const bool & loop)214 int32_t RingtonePlayer::Configure(const float &volume, const bool &loop)
215 {
216     AUDIO_INFO_LOG("RingtonePlayer::%{public}s", __func__);
217 
218     CHECK_AND_RETURN_RET_LOG(volume >= LOW_VOL && volume <= HIGH_VOL, ERR_INVALID_PARAM, "Volume level invalid");
219     CHECK_AND_RETURN_RET_LOG(player_ != nullptr && ringtoneState_ != STATE_INVALID, ERR_INVALID_PARAM, "no player_");
220 
221     loop_ = loop;
222     volume_ = volume;
223 
224     if (ringtoneState_ != STATE_NEW) {
225         (void)player_->SetVolume(volume_, volume_);
226         (void)player_->SetLooping(loop_);
227     }
228 
229     (void)PrepareRingtonePlayer(false);
230 
231     return SUCCESS;
232 }
233 
Start()234 int32_t RingtonePlayer::Start()
235 {
236     AUDIO_INFO_LOG("RingtonePlayer::%{public}s", __func__);
237 
238     CHECK_AND_RETURN_RET_LOG(player_ != nullptr && ringtoneState_ != STATE_INVALID, ERR_INVALID_PARAM, "no player_");
239 
240     if (player_->IsPlaying() || isStartQueued_) {
241         AUDIO_ERR_LOG("Play in progress, cannot start now");
242         return ERROR;
243     }
244 
245     // Player doesn't support play in stopped state. Hence reinitialise player for making start<-->stop to work
246     if (ringtoneState_ == STATE_STOPPED) {
247         (void)PrepareRingtonePlayer(true);
248     } else {
249         (void)PrepareRingtonePlayer(false);
250     }
251 
252     if (ringtoneState_ == STATE_NEW) {
253         AUDIO_INFO_LOG("Start received before player preparing is finished");
254         isStartQueued_ = true;
255         return SUCCESS;
256     }
257 
258     auto ret = player_->Play();
259     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERROR, "Start failed %{public}d", ret);
260 
261     ringtoneState_ = STATE_RUNNING;
262 
263     return SUCCESS;
264 }
265 
Stop()266 int32_t RingtonePlayer::Stop()
267 {
268     AUDIO_INFO_LOG("RingtonePlayer::%{public}s", __func__);
269     CHECK_AND_RETURN_RET_LOG(player_ != nullptr && ringtoneState_ != STATE_INVALID, ERR_INVALID_PARAM, "no player_");
270 
271     if (ringtoneState_ != STATE_STOPPED && player_->IsPlaying()) {
272         (void)player_->Stop();
273     }
274 
275     ringtoneState_ = STATE_STOPPED;
276     isStartQueued_ = false;
277 
278     return SUCCESS;
279 }
280 
Release()281 int32_t RingtonePlayer::Release()
282 {
283     AUDIO_INFO_LOG("RingtonePlayer::%{public}s player", __func__);
284 
285     if (player_ != nullptr) {
286         (void)player_->Release();
287     }
288 
289     ringtoneState_ = STATE_RELEASED;
290     player_ = nullptr;
291     callback_ = nullptr;
292 
293     return SUCCESS;
294 }
295 
GetRingtoneState()296 RingtoneState RingtonePlayer::GetRingtoneState()
297 {
298     AUDIO_INFO_LOG("RingtonePlayer::%{public}s", __func__);
299     return ringtoneState_;
300 }
301 
SetPlayerState(RingtoneState ringtoneState)302 void RingtonePlayer::SetPlayerState(RingtoneState ringtoneState)
303 {
304     CHECK_AND_RETURN_LOG(player_ != nullptr, "Ringtone player instance is null");
305 
306     if (ringtoneState_ != RingtoneState::STATE_RELEASED) {
307         ringtoneState_ = ringtoneState;
308     }
309 
310     if (ringtoneState_ == RingtoneState::STATE_PREPARED) {
311         AUDIO_INFO_LOG("Player prepared callback received. loop:%{public}d volume:%{public}f", loop_, volume_);
312 
313         Media::Format format;
314         format.PutIntValue(Media::PlayerKeys::CONTENT_TYPE, CONTENT_TYPE_RINGTONE);
315         format.PutIntValue(Media::PlayerKeys::STREAM_USAGE, STREAM_USAGE_NOTIFICATION_RINGTONE);
316 
317         (void)player_->SetParameter(format);
318         (void)player_->SetVolume(volume_, volume_);
319         (void)player_->SetLooping(loop_);
320 
321         if (isStartQueued_) {
322             auto ret = player_->Play();
323             isStartQueued_ = false;
324             CHECK_AND_RETURN_LOG(ret == SUCCESS, "Play failed %{public}d", ret);
325             ringtoneState_ = RingtoneState::STATE_RUNNING;
326         }
327     }
328 }
329 
GetAudioRendererInfo(AudioStandard::AudioRendererInfo & rendererInfo) const330 int32_t RingtonePlayer::GetAudioRendererInfo(AudioStandard::AudioRendererInfo &rendererInfo) const
331 {
332     AUDIO_INFO_LOG("RingtonePlayer::%{public}s", __func__);
333     rendererInfo.contentType = ContentType::CONTENT_TYPE_RINGTONE;
334     rendererInfo.streamUsage = StreamUsage::STREAM_USAGE_NOTIFICATION_RINGTONE;
335     rendererInfo.rendererFlags = 0;
336     return SUCCESS;
337 }
338 
GetTitle()339 std::string RingtonePlayer::GetTitle()
340 {
341     AUDIO_INFO_LOG("RingtonePlayer::%{public}s", __func__);
342     CHECK_AND_RETURN_RET_LOG(context_ != nullptr, "", "context cannot be null");
343 
344     auto ctxUri = make_unique<Uri>(Media::MEDIALIBRARY_DATA_URI);
345     CHECK_AND_RETURN_RET_LOG(ctxUri != nullptr, "", "failed to create context uri");
346 
347     shared_ptr<AppExecFwk::DataAbilityHelper> helper = AppExecFwk::DataAbilityHelper::Creator(context_, move(ctxUri));
348     CHECK_AND_RETURN_RET_LOG(helper != nullptr, "", "Unable to create data ability helper");
349 
350     Uri mediaLibUri(Media::MEDIALIBRARY_DATA_URI);
351 
352     vector<string> columns = {};
353     columns.push_back(Media::MEDIA_DATA_DB_TITLE);
354 
355     auto uri = audioRingtoneMgr_.GetSystemRingtoneUri(context_, type_);
356     DataAbilityPredicates predicates;
357     predicates.EqualTo(Media::MEDIA_DATA_DB_FILE_PATH, uri);
358 
359     shared_ptr<AbsSharedResultSet> resultSet = nullptr;
360     resultSet = helper->Query(mediaLibUri, columns, predicates);
361     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, "", "Unable to fetch details from path %s", uri.c_str());
362 
363     int ret = resultSet->GoToFirstRow();
364     CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, "", "Failed to obtain the record");
365 
366     int32_t titleIndex(0);
367     string title("");
368     resultSet->GetColumnIndex(Media::MEDIA_DATA_DB_TITLE, titleIndex);
369     resultSet->GetString(titleIndex, title);
370 
371     helper->Release();
372 
373     return title;
374 }
375 
376 // Callback class symbols
RingtonePlayerCallback(RingtonePlayer & ringtonePlayer)377 RingtonePlayerCallback::RingtonePlayerCallback(RingtonePlayer &ringtonePlayer) : ringtonePlayer_(ringtonePlayer)
378 {}
379 
OnError(PlayerErrorType errorType,int32_t errorCode)380 void RingtonePlayerCallback::OnError(PlayerErrorType errorType, int32_t errorCode)
381 {
382     AUDIO_ERR_LOG("Error reported from media server %{public}d", errorCode);
383 }
384 
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)385 void RingtonePlayerCallback::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
386 {
387     if (type != INFO_TYPE_STATE_CHANGE) {
388         return;
389     }
390     state_ = static_cast<PlayerStates>(extra);
391 
392     switch (state_) {
393         case PLAYER_STATE_ERROR:
394             ringtoneState_ = STATE_INVALID;
395             break;
396         case PLAYER_IDLE:
397         case PLAYER_INITIALIZED:
398         case PLAYER_PREPARING:
399             ringtoneState_ = STATE_NEW;
400             break;
401         case PLAYER_PREPARED:
402             ringtoneState_ = STATE_PREPARED;
403             break;
404         case PLAYER_STARTED:
405             ringtoneState_ = STATE_RUNNING;
406             break;
407         case PLAYER_PAUSED:
408             ringtoneState_ = STATE_PAUSED;
409             break;
410         case PLAYER_STOPPED:
411         case PLAYER_PLAYBACK_COMPLETE:
412             ringtoneState_ = STATE_STOPPED;
413             break;
414         default:
415             break;
416     }
417     ringtonePlayer_.SetPlayerState(ringtoneState_);
418 }
419 } // namesapce AudioStandard
420 } // namespace OHOS
421