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