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