• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2023 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  * Description: implement the cast session manager
15  * Author: zhangge
16  * Create: 2022-06-15
17  */
18 
19 #include <thread>
20 
21 #include "cast_session_manager.h"
22 
23 #include "cast_engine_errors.h"
24 #include "cast_engine_log.h"
25 #include "cast_session_manager_adaptor.h"
26 #include "cast_session_manager_service_proxy.h"
27 #include "i_cast_session.h"
28 #include "if_system_ability_manager.h"
29 #include "iservice_registry.h"
30 #include "system_ability_definition.h"
31 
32 namespace OHOS {
33 namespace CastEngine {
34 namespace CastEngineClient {
35 DEFINE_CAST_ENGINE_LABEL("Cast-Client-SessionManager");
36 namespace {
37 constexpr int WAIT_SERVICE_LOAD_TIME_OUT_SECOND = 2;
38 }
39 
CastSessionManager()40 CastSessionManager::CastSessionManager()
41 {
42     CLOGI("in");
43 }
44 
GetInstance()45 CastSessionManager &CastSessionManager::GetInstance()
46 {
47     static CastSessionManager instance {};
48     return instance;
49 }
50 
GetAdaptor()51 std::shared_ptr<ICastSessionManagerAdaptor> CastSessionManager::GetAdaptor()
52 {
53     CLOGI("in");
54     std::unique_lock<std::mutex> lock(mutex_);
55     if (adaptor_) {
56         return adaptor_;
57     }
58 
59     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
60     if (samgr == nullptr) {
61         CLOGE("Failed to get SA manager");
62         return nullptr;
63     }
64     sptr<CastEngineServiceLoadCallback> loadCallback = new (std::nothrow) CastEngineServiceLoadCallback();
65     if (loadCallback == nullptr) {
66         CLOGE("Failed to new object");
67         return nullptr;
68     }
69     constexpr int32_t retryTimes = 5;
70     int retryTime = 0;
71     bool ret = false;
72     isNeedLoadService_ = true;
73     while (!ret && retryTime < retryTimes) {
74         retryTime++;
75         if (isNeedLoadService_) {
76             auto result = samgr->LoadSystemAbility(CAST_ENGINE_SA_ID, loadCallback);
77             if (result != ERR_OK) {
78                 CLOGE("systemAbilityId: %d load failed, result code: %d", CAST_ENGINE_SA_ID, result);
79                 return nullptr;
80             }
81             isNeedLoadService_ = false;
82         }
83         ret = loadServiceCond_.wait_for(lock, std::chrono::seconds(WAIT_SERVICE_LOAD_TIME_OUT_SECOND),
84             [this] { return (adaptor_ != nullptr); });
85     }
86     if (!ret) {
87         CLOGE("wait service loaded timeout");
88         return nullptr;
89     }
90     return adaptor_;
91 }
92 
RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener)93 int32_t CastSessionManager::RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener)
94 {
95     CLOGI("in");
96     if (listener == nullptr) {
97         CLOGE("Failed to init due to the null listener");
98         return CAST_ENGINE_ERROR;
99     }
100     constexpr int32_t sleepTimeMs = 200;
101     constexpr int32_t retryTimes = 1;
102     int retryTime = 0;
103     bool retry = false;
104     do {
105         retry = false;
106         auto adaptor = GetAdaptor();
107         if (!adaptor) {
108             return CAST_ENGINE_ERROR;
109         }
110         sptr<CastEngineServiceDeathRecipient> deathRecipient(
111             new (std::nothrow) CastEngineServiceDeathRecipient(listener));
112         if (!deathRecipient) {
113             CLOGE("Death recipient malloc failed");
114             return CAST_ENGINE_ERROR;
115         }
116         int32_t ret = adaptor->RegisterListener(listener, deathRecipient);
117         if (ret == CAST_ENGINE_SUCCESS) {
118             std::lock_guard<std::mutex> lock(mutex_);
119             deathRecipient_ = deathRecipient;
120             return CAST_ENGINE_SUCCESS;
121         }
122         if (ret == ERR_SERVICE_IS_UNLOADING && retryTime < retryTimes) {
123             CLOGI("cast service is unloading, wait and retry angain");
124             std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
125             retry = true;
126             retryTime++;
127             std::lock_guard<std::mutex> lock(mutex_);
128             adaptor_ = nullptr;
129         }
130     } while (retry);
131     return CAST_ENGINE_ERROR;
132 }
133 
UnregisterListener()134 int32_t CastSessionManager::UnregisterListener()
135 {
136     CLOGI("in");
137     ReleaseServiceDeathRecipient();
138     auto adaptor = GetAdaptor();
139     int32_t ret = adaptor ? adaptor->UnregisterListener() : CAST_ENGINE_ERROR;
140     std::lock_guard<std::mutex> lock(mutex_);
141     adaptor_.reset();
142     return ret;
143 }
144 
Release()145 int32_t CastSessionManager::Release()
146 {
147     CLOGI("in");
148     ReleaseServiceDeathRecipient();
149     auto adaptor = GetAdaptor();
150     int32_t ret = adaptor ? adaptor->Release() : CAST_ENGINE_ERROR;
151     std::lock_guard<std::mutex> lock(mutex_);
152     adaptor_.reset();
153     return ret;
154 }
155 
SetLocalDevice(const CastLocalDevice & localDevice)156 int32_t CastSessionManager::SetLocalDevice(const CastLocalDevice &localDevice)
157 {
158     CLOGI("in");
159     if (localDevice.deviceId.empty()) {
160         CLOGE("Local device id is null");
161         return CAST_ENGINE_ERROR;
162     }
163     auto adaptor = GetAdaptor();
164     return adaptor ? adaptor->SetLocalDevice(localDevice) : CAST_ENGINE_ERROR;
165 }
166 
CreateCastSession(const CastSessionProperty & property,std::shared_ptr<ICastSession> & castSession)167 int32_t CastSessionManager::CreateCastSession(const CastSessionProperty &property,
168     std::shared_ptr<ICastSession> &castSession)
169 {
170     CLOGI("in");
171     auto adaptor = GetAdaptor();
172     return adaptor ? adaptor->CreateCastSession(property, castSession) : CAST_ENGINE_ERROR;
173 }
174 
SetSinkSessionCapacity(int sessionCapacity)175 int32_t CastSessionManager::SetSinkSessionCapacity(int sessionCapacity)
176 {
177     CLOGD("in");
178     auto adaptor = GetAdaptor();
179     return adaptor ? adaptor->SetSinkSessionCapacity(sessionCapacity) : CAST_ENGINE_ERROR;
180 }
181 
StartDiscovery(int protocols,std::vector<std::string> drmSchemes)182 int32_t CastSessionManager::StartDiscovery(int protocols, std::vector<std::string> drmSchemes)
183 {
184     CLOGD("in");
185     auto adaptor = GetAdaptor();
186     return adaptor ? adaptor->StartDiscovery(protocols, drmSchemes) : CAST_ENGINE_ERROR;
187 }
188 
SetDiscoverable(bool enable)189 int32_t CastSessionManager::SetDiscoverable(bool enable)
190 {
191     CLOGI("in");
192     auto adaptor = GetAdaptor();
193     return adaptor ? adaptor->SetDiscoverable(enable) : CAST_ENGINE_ERROR;
194 }
195 
StopDiscovery()196 int32_t CastSessionManager::StopDiscovery()
197 {
198     CLOGI("in");
199     auto adaptor = GetAdaptor();
200     return adaptor ? adaptor->StopDiscovery() : CAST_ENGINE_ERROR;
201 }
202 
StartDeviceLogging(int32_t fd,uint32_t maxSize)203 int32_t CastSessionManager::StartDeviceLogging(int32_t fd, uint32_t maxSize)
204 {
205     CLOGI("in");
206     auto adaptor = GetAdaptor();
207     return adaptor ? adaptor->StartDeviceLogging(fd, maxSize) : CAST_ENGINE_ERROR;
208 }
209 
GetCastSession(std::string sessionId,std::shared_ptr<ICastSession> & castSession)210 int32_t CastSessionManager::GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession)
211 {
212     CLOGI("in");
213     auto adaptor = GetAdaptor();
214     return adaptor ? adaptor->GetCastSession(sessionId, castSession) : CAST_ENGINE_ERROR;
215 }
216 
ReleaseClientResources()217 void CastSessionManager::ReleaseClientResources()
218 {
219     CLOGD("Release client resources");
220     std::shared_ptr<ICastSessionManagerListener> listener;
221     {
222         std::lock_guard<std::mutex> lock(mutex_);
223         if (!!deathRecipient_) {
224             listener = deathRecipient_->GetListener();
225         }
226 
227         deathRecipient_.clear();
228         adaptor_.reset();
229     }
230     if (listener) {
231         listener->OnServiceDied();
232     } else {
233         CLOGE("Report is nullptr");
234     }
235 }
236 
ReleaseServiceDeathRecipient()237 void CastSessionManager::ReleaseServiceDeathRecipient()
238 {
239     std::lock_guard<std::mutex> lock(mutex_);
240     deathRecipient_.clear();
241 }
242 
NotifyServiceLoadResult(const sptr<IRemoteObject> & remoteObject)243 void CastSessionManager::NotifyServiceLoadResult(const sptr<IRemoteObject> &remoteObject)
244 {
245     std::lock_guard<std::mutex> lock(mutex_);
246     isNeedLoadService_ = true;
247     if (!remoteObject || adaptor_) {
248         CLOGE("object is nullptr or adaptor_ is existed");
249         loadServiceCond_.notify_all();
250         return;
251     }
252     auto proxy = iface_cast<CastSessionManagerServiceProxy>(remoteObject);
253     adaptor_ = std::make_shared<CastSessionManagerAdaptor>(proxy);
254     loadServiceCond_.notify_all();
255 }
256 
OnRemoteDied(const wptr<IRemoteObject> & object)257 void CastSessionManager::CastEngineServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
258 {
259     CLOGE("Service died, need release resources");
260     CastSessionManager::GetInstance().ReleaseClientResources();
261 }
262 } // namespace CastEngineClient
263 } // namespace CastEngine
264 } // namespace OHOS
265