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