• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "media_avsession_adapter_impl.h"
17 
18 #include "ability_manager_client.h"
19 #include "avsession_errors.h"
20 #include "avsession_manager.h"
21 #include "bundle_mgr_proxy.h"
22 #include "element_name.h"
23 #include "if_system_ability_manager.h"
24 #include "iservice_registry.h"
25 #include "native_interface_bundle.h"
26 #include "nweb_log.h"
27 #include "parameters.h"
28 #include "system_ability_definition.h"
29 
30 namespace OHOS::NWeb {
31 
32 std::unordered_map<std::string, std::shared_ptr<AVSession::AVSession>> MediaAVSessionAdapterImpl::avSessionMap;
33 
34 constexpr int64_t LIVE_STREAM_INFINITE_DURATION = -1;
35 
MediaAVSessionCallbackImpl(std::shared_ptr<MediaAVSessionCallbackAdapter> callbackAdapter)36 MediaAVSessionCallbackImpl::MediaAVSessionCallbackImpl(
37     std::shared_ptr<MediaAVSessionCallbackAdapter> callbackAdapter)
38     : callbackAdapter_(callbackAdapter)
39 {
40 }
41 
OnPlay()42 void MediaAVSessionCallbackImpl::OnPlay()
43 {
44     if (callbackAdapter_) {
45         callbackAdapter_->Play();
46     }
47 }
48 
OnPause()49 void MediaAVSessionCallbackImpl::OnPause()
50 {
51     if (callbackAdapter_) {
52         callbackAdapter_->Pause();
53     }
54 }
55 
OnStop()56 void MediaAVSessionCallbackImpl::OnStop()
57 {
58     if (callbackAdapter_) {
59         callbackAdapter_->Stop();
60     }
61 }
62 
OnPlayNext()63 void MediaAVSessionCallbackImpl::OnPlayNext()
64 {
65 }
66 
OnPlayPrevious()67 void MediaAVSessionCallbackImpl::OnPlayPrevious()
68 {
69 }
70 
OnFastForward(int64_t time)71 void MediaAVSessionCallbackImpl::OnFastForward(int64_t time)
72 {
73 }
74 
OnRewind(int64_t time)75 void MediaAVSessionCallbackImpl::OnRewind(int64_t time)
76 {
77 }
78 
OnSeek(int64_t time)79 void MediaAVSessionCallbackImpl::OnSeek(int64_t time)
80 {
81     if (callbackAdapter_) {
82         callbackAdapter_->SeekTo(time);
83     }
84 }
85 
OnSetSpeed(double speed)86 void MediaAVSessionCallbackImpl::OnSetSpeed(double speed)
87 {
88 }
89 
OnSetLoopMode(int32_t loopMode)90 void MediaAVSessionCallbackImpl::OnSetLoopMode(int32_t loopMode)
91 {
92 }
93 
OnToggleFavorite(const std::string & assertId)94 void MediaAVSessionCallbackImpl::OnToggleFavorite(const std::string& assertId)
95 {
96 }
97 
OnMediaKeyEvent(const MMI::KeyEvent & keyEvent)98 void MediaAVSessionCallbackImpl::OnMediaKeyEvent(const MMI::KeyEvent& keyEvent)
99 {
100 }
101 
OnOutputDeviceChange(const int32_t connectionState,const AVSession::OutputDeviceInfo & outputDeviceInfo)102 void MediaAVSessionCallbackImpl::OnOutputDeviceChange(const int32_t connectionState,
103     const AVSession::OutputDeviceInfo& outputDeviceInfo)
104 {
105 }
106 
OnCommonCommand(const std::string & commonCommand,const AAFwk::WantParams & commandArgs)107 void MediaAVSessionCallbackImpl::OnCommonCommand(
108     const std::string& commonCommand,
109     const AAFwk::WantParams& commandArgs)
110 {
111 }
112 
OnSkipToQueueItem(int32_t itemId)113 void MediaAVSessionCallbackImpl::OnSkipToQueueItem(int32_t itemId)
114 {
115 }
116 
OnAVCallAnswer()117 void MediaAVSessionCallbackImpl::OnAVCallAnswer()
118 {
119 }
120 
OnAVCallHangUp()121 void MediaAVSessionCallbackImpl::OnAVCallHangUp()
122 {
123 }
124 
OnAVCallToggleCallMute()125 void MediaAVSessionCallbackImpl::OnAVCallToggleCallMute()
126 {
127 }
128 
OnPlayFromAssetId(int64_t assetId)129 void MediaAVSessionCallbackImpl::OnPlayFromAssetId(int64_t assetId)
130 {
131 }
132 
OnCastDisplayChange(const AVSession::CastDisplayInfo & castDisplayInfo)133 void MediaAVSessionCallbackImpl::OnCastDisplayChange(
134     const AVSession::CastDisplayInfo& castDisplayInfo)
135 {
136 }
137 
Init()138 void MediaAVSessionKey::Init()
139 {
140     pid_ = getprocpid();
141     element_ = AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility();
142     WVLOG_I("media avsession adapter Init AAFwk BundleName=%{public}s, AbilityName=%{public}s",
143             element_.GetBundleName().c_str(), element_.GetAbilityName().c_str());
144     auto context = AbilityRuntime::ApplicationContext::GetApplicationContext();
145     if (context) {
146         element_.SetBundleName(context->GetBundleName());
147         WVLOG_I("media avsession adapter Init context BundleName()=%{public}s", context->GetBundleName().c_str());
148     }
149     type_ = MediaAVSessionType::MEDIA_TYPE_INVALID;
150 
151     // SA application can get AbilityName by GetTopAbility, but others cannnot.
152     if (!element_.GetAbilityName().empty()) {
153         WVLOG_I("media avsession adapter Init element_.GetAbilityName()=%{public}s", element_.GetAbilityName().c_str());
154         return;
155     }
156 
157     OH_NativeBundle_ElementName bundleInfo = OH_NativeBundle_GetMainElementName();
158     WVLOG_I("OH_NativeBundle_GetMainElementName, bundleName=%{public}s, abilityName=%{public}s", bundleInfo.bundleName,
159         bundleInfo.abilityName);
160     if (bundleInfo.abilityName) {
161         element_.SetAbilityName(std::string(bundleInfo.abilityName));
162     }
163 }
164 
GetPID()165 int32_t MediaAVSessionKey::GetPID()
166 {
167     return pid_;
168 }
169 
GetElement()170 AppExecFwk::ElementName MediaAVSessionKey::GetElement()
171 {
172     return element_;
173 }
174 
SetType(MediaAVSessionType type)175 void MediaAVSessionKey::SetType(MediaAVSessionType type)
176 {
177     type_ = type;
178 }
179 
GetType()180 MediaAVSessionType MediaAVSessionKey::GetType()
181 {
182     return type_;
183 }
184 
ToString()185 std::string MediaAVSessionKey::ToString()
186 {
187     return (std::to_string(pid_) + "_" + element_.GetBundleName() + "_" + element_.GetAbilityName());
188 }
189 
MediaAVSessionAdapterImpl()190 MediaAVSessionAdapterImpl::MediaAVSessionAdapterImpl()
191 {
192     avSessionKey_ = std::make_shared<MediaAVSessionKey>();
193     avSessionKey_->Init();
194     avMetadata_ = std::make_shared<AVSession::AVMetaData>();
195     avMetadata_->SetAssetId(std::to_string(avSessionKey_->GetPID()));
196     avPlaybackState_ = std::make_shared<AVSession::AVPlaybackState>();
197 }
198 
~MediaAVSessionAdapterImpl()199 MediaAVSessionAdapterImpl::~MediaAVSessionAdapterImpl()
200 {
201     DestroyAVSession();
202 }
203 
CreateAVSession(MediaAVSessionType type)204 bool MediaAVSessionAdapterImpl::CreateAVSession(MediaAVSessionType type)
205 {
206     WVLOG_I("media avsession adapter CreateAVSession in, type=%{public}d", int32_t(type));
207     if (MediaAVSessionType::MEDIA_TYPE_INVALID == type) {
208         WVLOG_E("media avsession adapter CreateAVSession, type invalid return false");
209         return false;
210     }
211     if (avSession_ && (type != avSessionKey_->GetType())) {
212         DestroyAVSession();
213     }
214     auto findIter = avSessionMap.find(avSessionKey_->ToString());
215     if (!avSession_) {
216         if (findIter != avSessionMap.end()) {
217             DestroyAndEraseSession();
218         }
219         return CreateNewSession(type);
220     } else {
221         if (findIter != avSessionMap.end()) {
222             if (findIter->second.get() != avSession_.get()) {
223                 DestroyAndEraseSession();
224                 DestroyAVSession();
225             } else {
226                 WVLOG_E("media avsession adapter CreateAVSession, return false");
227                 return false;
228             }
229         }
230         return CreateNewSession(type);
231     }
232 }
233 
DestroyAVSession()234 void MediaAVSessionAdapterImpl::DestroyAVSession()
235 {
236     WVLOG_I("media avsession adapter DestroyAVSession in");
237     if (avSession_) {
238         int32_t ret = avSession_->Destroy();
239         if (ret != AVSession::AVSESSION_SUCCESS) {
240             WVLOG_E("media avsession adapter DestroyAVSession Destroy() failed, ret: %{public}d", ret);
241         } else {
242             WVLOG_I("media avsession adapter DestroyAVSession Destroy() success, ret: %{public}d", ret);
243         }
244         avSession_.reset();
245     }
246     auto iter = avSessionMap.find(avSessionKey_->ToString());
247     if (iter != avSessionMap.end()) {
248         avSessionMap.erase(iter);
249     }
250     WVLOG_I("media avsession adapter DestroyAVSession out");
251 }
252 
RegistCallback(std::shared_ptr<MediaAVSessionCallbackAdapter> callbackAdapter)253 bool MediaAVSessionAdapterImpl::RegistCallback(
254     std::shared_ptr<MediaAVSessionCallbackAdapter> callbackAdapter)
255 {
256     WVLOG_I("media avsession adapter RegistCallback in");
257 
258     if (avSession_ && Activate()) {
259         auto callback = std::make_shared<MediaAVSessionCallbackImpl>(callbackAdapter);
260         int32_t ret = avSession_->RegisterCallback(callback);
261         if (ret != AVSession::AVSESSION_SUCCESS) {
262             WVLOG_E("media avsession adapter RegistCallback RegisterCallback() failed, ret: %{public}d", ret);
263             return false;
264         }
265         static const std::vector<int32_t> commands = {
266             AVSession::AVControlCommand::SESSION_CMD_PLAY,
267             AVSession::AVControlCommand::SESSION_CMD_PAUSE,
268             AVSession::AVControlCommand::SESSION_CMD_STOP,
269             AVSession::AVControlCommand::SESSION_CMD_SEEK
270         };
271         for (auto command : commands) {
272             ret = avSession_->AddSupportCommand(command);
273             if (ret != AVSession::AVSESSION_SUCCESS) {
274                 WVLOG_E("media avsession adapter RegistCallback AddSupportCommand() '%{public}d' failed", command);
275             } else {
276                 WVLOG_I("media avsession adapter RegistCallback AddSupportCommand() '%{public}d' success", command);
277             }
278         }
279         WVLOG_I("media avsession adapter RegistCallback out return true");
280         return true;
281     }
282     WVLOG_I("media avsession adapter RegistCallback out return false");
283     return false;
284 }
285 
IsActivated()286 bool MediaAVSessionAdapterImpl::IsActivated()
287 {
288     WVLOG_I("media avsession adapter IsActivated in");
289     if (avSession_) {
290         bool ret = avSession_->IsActive();
291         WVLOG_I("media avsession adapter IsActive out ret: %{public}d", ret);
292         return ret;
293     }
294     WVLOG_E("media avsession adapter IsActivated out avSession is null, return false");
295     return false;
296 }
297 
Activate()298 bool MediaAVSessionAdapterImpl::Activate()
299 {
300     if (!avSession_) {
301         WVLOG_E("media avsession adapter Activate avSession_ is null, return false");
302         return false;
303     } else if (avSession_->IsActive()) {
304         WVLOG_I("media avsession adapter Activate IsActive() is true, return true");
305         return true;
306     }
307     int32_t ret = avSession_->Activate();
308     if (ret != AVSession::AVSESSION_SUCCESS) {
309         WVLOG_E("media avsession adapter Activate Activate() failed, ret: %{public}d", ret);
310         return false;
311     }
312     WVLOG_I("media avsession adapter Activate return true");
313     return true;
314 }
315 
DeActivate()316 void MediaAVSessionAdapterImpl::DeActivate()
317 {
318     if (avSession_ && avSession_->IsActive()) {
319         int32_t ret = avSession_->Deactivate();
320         if (ret != AVSession::AVSESSION_SUCCESS) {
321             WVLOG_E("media avsession adapter deactivate avsession failed, ret: %{public}d", ret);
322         }
323     }
324 }
325 
SetMetadata(const std::shared_ptr<MediaAVSessionMetadataAdapter> metadata)326 void MediaAVSessionAdapterImpl::SetMetadata(const std::shared_ptr<MediaAVSessionMetadataAdapter> metadata)
327 {
328     UpdateMetaDataCache(metadata);
329     if (avSession_) {
330         Activate();
331         auto avMetadata = avMetadata_.get();
332         int32_t ret = avSession_->SetAVMetaData(*avMetadata);
333         if (ret != AVSession::AVSESSION_SUCCESS) {
334             WVLOG_E("media avsession adapter SetMetadata SetAVMetaData() failed, ret: %{public}d", ret);
335         } else {
336             WVLOG_I("media avsession adapter SetMetadata SetAVMetaData() success, ret: %{public}d", ret);
337         }
338     }
339 }
340 
SetPlaybackState(MediaAVSessionPlayState state)341 void MediaAVSessionAdapterImpl::SetPlaybackState(MediaAVSessionPlayState state)
342 {
343     if (UpdatePlaybackStateCache(state) && avSession_) {
344         Activate();
345         auto avPlaybackState = avPlaybackState_.get();
346         int32_t ret = avSession_->SetAVPlaybackState(*avPlaybackState);
347         if (ret != AVSession::AVSESSION_SUCCESS) {
348             WVLOG_E("media avsession adapter SetPlaybackState SetAVPlaybackState() failed, ret: %{public}d", ret);
349         } else {
350             WVLOG_I("media avsession adapter SetPlaybackState SetAVPlaybackState() success, ret: %{public}d", ret);
351         }
352     }
353 }
354 
SetPlaybackPosition(const std::shared_ptr<MediaAVSessionPositionAdapter> position)355 void MediaAVSessionAdapterImpl::SetPlaybackPosition(const std::shared_ptr<MediaAVSessionPositionAdapter> position)
356 {
357     if (UpdateMetaDataCache(position) && avSession_) {
358         Activate();
359         auto avMetadata = avMetadata_.get();
360         int32_t ret = avSession_->SetAVMetaData(*avMetadata);
361         if (ret != AVSession::AVSESSION_SUCCESS) {
362             WVLOG_E("media avsession adapter SetPlaybackPosition SetAVMetaData() failed, ret: %{public}d", ret);
363         } else {
364             WVLOG_I("media avsession adapter SetPlaybackPosition SetAVMetaData() success, ret: %{public}d", ret);
365         }
366     }
367     if (UpdatePlaybackStateCache(position) && avSession_) {
368         Activate();
369         auto avPlaybackState = avPlaybackState_.get();
370         int32_t ret = avSession_->SetAVPlaybackState(*avPlaybackState);
371         if (ret != AVSession::AVSESSION_SUCCESS) {
372             WVLOG_E("media avsession adapter SetPlaybackPosition SetAVPlaybackState() failed, ret: %{public}d", ret);
373         } else {
374             WVLOG_I("media avsession adapter SetPlaybackPosition SetAVPlaybackState() success, ret: %{public}d", ret);
375         }
376     }
377 }
378 
UpdateMetaDataCache(const std::shared_ptr<MediaAVSessionMetadataAdapter> metadata)379 bool MediaAVSessionAdapterImpl::UpdateMetaDataCache(const std::shared_ptr<MediaAVSessionMetadataAdapter> metadata)
380 {
381     bool updated = false;
382     if (avMetadata_->GetTitle() != metadata->GetTitle()) {
383         avMetadata_->SetTitle(metadata->GetTitle());
384         updated = true;
385     }
386     if (avMetadata_->GetArtist() != metadata->GetArtist()) {
387         avMetadata_->SetArtist(metadata->GetArtist());
388         updated = true;
389     }
390     if (avMetadata_->GetAlbum() != metadata->GetAlbum()) {
391         avMetadata_->SetAlbum(metadata->GetAlbum());
392         updated = true;
393     }
394     if (avMetadata_->GetMediaImageUri() != metadata->GetImageUrl()) {
395         avMetadata_->SetMediaImageUri(metadata->GetImageUrl());
396         updated = true;
397     }
398     WVLOG_I("media avsession adapter UpdateMetaDataCache return updated: %{public}d", updated);
399     return updated;
400 }
401 
UpdateMetaDataCache(const std::shared_ptr<MediaAVSessionPositionAdapter> position)402 bool MediaAVSessionAdapterImpl::UpdateMetaDataCache(const std::shared_ptr<MediaAVSessionPositionAdapter> position)
403 {
404     if (!position) {
405         WVLOG_E("position is nullptr, media avsession adapter UpdateMetaDataCache return false");
406         return false;
407     }
408     int64_t getDuration = position->GetDuration();
409     if (avMetadata_->GetDuration() != getDuration) {
410         if (getDuration < INT64_MAX) {
411             avMetadata_->SetDuration(getDuration);
412         } else {
413             avMetadata_->SetDuration(LIVE_STREAM_INFINITE_DURATION);
414         }
415         return true;
416     }
417     WVLOG_E("media avsession adapter UpdateMetaDataCache return false");
418     return false;
419 }
420 
UpdatePlaybackStateCache(MediaAVSessionPlayState state)421 bool MediaAVSessionAdapterImpl::UpdatePlaybackStateCache(MediaAVSessionPlayState state)
422 {
423     int32_t currentState;
424     switch (state) {
425         case MediaAVSessionPlayState::STATE_PLAY:
426             currentState = AVSession::AVPlaybackState::PLAYBACK_STATE_PLAY;
427             break;
428         case MediaAVSessionPlayState::STATE_PAUSE:
429             currentState = AVSession::AVPlaybackState::PLAYBACK_STATE_PAUSE;
430             break;
431         case MediaAVSessionPlayState::STATE_INITIAL:
432         default:
433             currentState = AVSession::AVPlaybackState::PLAYBACK_STATE_INITIAL;
434             break;
435     }
436     if (avPlaybackState_->GetState() != currentState) {
437         avPlaybackState_->SetState(currentState);
438         WVLOG_I("media avsession adapter UpdatePlaybackStateCache return true");
439         return true;
440     }
441     WVLOG_E("media avsession adapter UpdatePlaybackStateCache return false");
442     return false;
443 }
444 
UpdatePlaybackStateCache(const std::shared_ptr<MediaAVSessionPositionAdapter> position)445 bool MediaAVSessionAdapterImpl::UpdatePlaybackStateCache(
446     const std::shared_ptr<MediaAVSessionPositionAdapter> position)
447 {
448     bool updated = false;
449     auto duration = static_cast<int32_t>(position->GetDuration());
450     if (avPlaybackState_->GetDuration() != duration) {
451         avPlaybackState_->SetDuration(duration);
452         updated = true;
453     }
454     auto avPosition = avPlaybackState_->GetPosition();
455     if ((avPosition.elapsedTime_ != position->GetElapsedTime()) ||
456         (avPosition.updateTime_ != position->GetUpdateTime())) {
457         avPosition.elapsedTime_ = position->GetElapsedTime();
458         avPosition.updateTime_ = position->GetUpdateTime();
459         avPlaybackState_->SetPosition(avPosition);
460         updated = true;
461     }
462     WVLOG_I("media avsession adapter UpdatePlaybackStateCache return updated: %{public}d", updated);
463     return updated;
464 }
465 
DestroyAndEraseSession()466 void MediaAVSessionAdapterImpl::DestroyAndEraseSession()
467 {
468     WVLOG_I("media avsession adapter DestroyAndEraseSession in");
469     auto iter = avSessionMap.find(avSessionKey_->ToString());
470     if (iter == avSessionMap.end()) {
471         WVLOG_E("media avsession adapter DestroyAndEraseSession invalid iterator return");
472         return;
473     }
474     if (!iter->second) {
475         avSessionMap.erase(iter);
476         WVLOG_E("media avsession adapter DestroyAndEraseSession avsession is null pointer return");
477         return;
478     }
479     int32_t ret = iter->second->Destroy();
480     if (ret != AVSession::AVSESSION_SUCCESS) {
481         WVLOG_E("media avsession adapter DestroyAndEraseSession Destroy failed, ret: %{public}d", ret);
482     } else {
483         WVLOG_I("media avsession adapter DestroyAndEraseSession Destroy success, ret: %{public}d", ret);
484     }
485     iter->second.reset();
486     avSessionMap.erase(iter);
487     WVLOG_I("media avsession adapter DestroyAndEraseSession out");
488 }
489 
CreateNewSession(const MediaAVSessionType & type)490 bool MediaAVSessionAdapterImpl::CreateNewSession(const MediaAVSessionType& type)
491 {
492     WVLOG_I("media avsession adapter CreateNewSession in");
493     avSession_ = AVSession::AVSessionManager::GetInstance().CreateSession(
494         avSessionKey_->GetElement().GetBundleName(), static_cast<int32_t>(type), avSessionKey_->GetElement());
495     if (avSession_) {
496         avSessionKey_->SetType(type);
497         avSessionMap.insert(
498             std::pair<std::string, std::shared_ptr<AVSession::AVSession>>(avSessionKey_->ToString(), avSession_));
499         return true;
500     } else {
501         WVLOG_E("media avsession adapter CreateNewSession Fail, out return false");
502         return false;
503     }
504 }
505 
506 } // namespace OHOS::NWeb