1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
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 "avsession_background.h"
17 #include <unistd.h>
18 #include "player.h"
19 #include "player_server.h"
20 #include "media_dfx.h"
21 #include "media_log.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVSessionBackGround"};
25 }
26
27 namespace OHOS {
28 namespace Media {
29 std::shared_ptr<AVsessionBackground> AVsessionBackground::instance_;
30 std::once_flag AVsessionBackground::onceFlag_;
31
Instance()32 AVsessionBackground &AVsessionBackground::Instance()
33 {
34 std::call_once(onceFlag_, [] {
35 instance_ = std::make_shared<AVsessionBackground>();
36 });
37 return *instance_;
38 }
39
AVsessionBackground()40 AVsessionBackground::AVsessionBackground()
41 {
42 MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
43 }
44
~AVsessionBackground()45 AVsessionBackground::~AVsessionBackground()
46 {
47 MEDIA_LOGI("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
48 }
49
Init()50 void AVsessionBackground::Init()
51 {
52 if (!init_) {
53 MEDIA_LOGI("AVSession::AVSessionManager::RegisterSessionListener");
54 int32_t ret = AVSession::AVSessionManager::GetInstance().RegisterSessionListener(shared_from_this());
55 CHECK_AND_RETURN_LOG(ret == 0, "failed to AVSessionManager::RegisterSessionListener");
56 init_ = (ret == 0) ? true : false;
57 }
58 }
59
AddListener(std::weak_ptr<IPlayerService> player,int32_t uid)60 void AVsessionBackground::AddListener(std::weak_ptr<IPlayerService> player, int32_t uid)
61 {
62 Init();
63 std::lock_guard<std::mutex> lock(mutex_);
64 // clean map/list from listener list/map
65 for (auto it1 = playerMap_.begin(); it1 != playerMap_.end();) {
66 std::list<std::weak_ptr<IPlayerService>> &playerList = it1->second;
67 for (auto it2 = playerList.begin(); it2 != playerList.end();) {
68 std::weak_ptr<IPlayerService> &temp = *it2;
69 if (temp.lock() == nullptr) {
70 it2 = playerList.erase(it2);
71 } else {
72 ++it2;
73 }
74 }
75 if (playerList.empty()) {
76 it1 = playerMap_.erase(it1);
77 } else {
78 ++it1;
79 }
80 }
81 MEDIA_LOGI("DelListener uid num %{public}zu", playerMap_.size());
82
83 // add player to listener list/map
84 auto it = playerMap_.find(uid);
85 if (it != playerMap_.end()) {
86 std::list<std::weak_ptr<IPlayerService>> &playerList = it->second;
87 playerList.push_back(player);
88 MEDIA_LOGI("AddListener uid %{public}d, player num %{public}zu", uid, playerList.size());
89 } else {
90 std::list<std::weak_ptr<IPlayerService>> playerList;
91 playerList.push_back(player);
92 playerMap_[uid] = playerList;
93 MEDIA_LOGI("AddListener uid %{public}d, player num %{public}zu", uid, playerList.size());
94 }
95 }
96
OnAudioSessionChecked(const int32_t uid)97 void AVsessionBackground::OnAudioSessionChecked(const int32_t uid)
98 {
99 std::list<std::weak_ptr<IPlayerService>> playerList;
100 {
101 std::lock_guard<std::mutex> lock(mutex_);
102 auto it1 = playerMap_.find(uid);
103 if (it1 != playerMap_.end()) {
104 playerList = it1->second; // copylist and unlock mutex, Avoid locking the addlist
105 }
106 }
107
108 MEDIA_LOGW("The application uid %{public}d has not registered avsession", uid);
109 for (auto &it2 : playerList) {
110 auto player = it2.lock();
111 if (player != nullptr && player->IsPlaying()) {
112 MediaTrace trace("AVsessionBackground::Pause");
113 auto playerServer = std::static_pointer_cast<PlayerServer>(player);
114 (void)playerServer->BackGroundChangeState(PlayerStates::PLAYER_PAUSED, true);
115 MEDIA_LOGW("The application has been logged back to the background");
116 }
117 }
118 }
119 } // namespace Media
120 } // namespace OHOS