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