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