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 <thread>
24
25 #include "cast_engine_errors.h"
26 #include "cast_engine_log.h"
27 #include "cast_engine_service_load_callback.h"
28 #include "cast_session_manager_adaptor.h"
29 #include "cast_session_manager_service_proxy.h"
30 #include "i_cast_session.h"
31 #include "if_system_ability_manager.h"
32 #include "iservice_registry.h"
33 #include "system_ability_definition.h"
34
35 namespace OHOS {
36 namespace CastEngine {
37 namespace CastEngineClient {
38 DEFINE_CAST_ENGINE_LABEL("Cast-Client-SessionManager");
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::lock_guard<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
70 auto result = samgr->LoadSystemAbility(CAST_ENGINE_SA_ID, loadCallback);
71 if (result != ERR_OK) {
72 CLOGE("systemAbilityId: %d load failed, result code: %d", CAST_ENGINE_SA_ID, result);
73 return nullptr;
74 }
75
76 constexpr int32_t sleepTimeMs = 30;
77 constexpr int32_t retryTimes = 150; // The service startup timeout interval is 4s.
78 int32_t retryTime = 0;
79
80 sptr<IRemoteObject> object;
81 while ((object = samgr->CheckSystemAbility(CAST_ENGINE_SA_ID)) == nullptr && (retryTime < retryTimes)) {
82 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
83 retryTime++;
84 }
85 if (object == nullptr) {
86 CLOGE("Failed to get cast engine manager");
87 return nullptr;
88 }
89
90 auto proxy = iface_cast<CastSessionManagerServiceProxy>(object);
91 adaptor_ = std::make_shared<CastSessionManagerAdaptor>(proxy);
92 return adaptor_;
93 }
94
RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener)95 int32_t CastSessionManager::RegisterListener(std::shared_ptr<ICastSessionManagerListener> listener)
96 {
97 CLOGI("in");
98 if (listener == nullptr) {
99 CLOGE("Failed to init due to the null listener");
100 return CAST_ENGINE_ERROR;
101 }
102 auto adaptor = GetAdaptor();
103 if (!adaptor) {
104 return CAST_ENGINE_ERROR;
105 }
106 sptr<CastEngineServiceDeathRecipient> deathRecipient(
107 new (std::nothrow) CastEngineServiceDeathRecipient(listener));
108 if (!deathRecipient) {
109 CLOGE("Death recipient malloc failed");
110 return CAST_ENGINE_ERROR;
111 }
112 if (adaptor->RegisterListener(listener, deathRecipient) == CAST_ENGINE_SUCCESS) {
113 std::lock_guard<std::mutex> lock(mutex_);
114 deathRecipient_ = deathRecipient;
115 return CAST_ENGINE_SUCCESS;
116 }
117 return CAST_ENGINE_ERROR;
118 }
119
UnregisterListener()120 int32_t CastSessionManager::UnregisterListener()
121 {
122 CLOGI("in");
123 ReleaseServiceDeathRecipient();
124 auto adaptor = GetAdaptor();
125 int32_t ret = adaptor ? adaptor->UnregisterListener() : CAST_ENGINE_ERROR;
126 std::lock_guard<std::mutex> lock(mutex_);
127 adaptor_ = nullptr;
128 return ret;
129 }
130
Release()131 int32_t CastSessionManager::Release()
132 {
133 CLOGI("in");
134 ReleaseServiceDeathRecipient();
135 auto adaptor = GetAdaptor();
136 int32_t ret = adaptor ? adaptor->Release() : CAST_ENGINE_ERROR;
137 std::lock_guard<std::mutex> lock(mutex_);
138 adaptor_ = nullptr;
139 return ret;
140 }
141
SetLocalDevice(const CastLocalDevice &localDevice)142 int32_t CastSessionManager::SetLocalDevice(const CastLocalDevice &localDevice)
143 {
144 CLOGI("in");
145 if (localDevice.deviceId.empty()) {
146 CLOGE("Local device id is null");
147 return CAST_ENGINE_ERROR;
148 }
149 auto adaptor = GetAdaptor();
150 return adaptor ? adaptor->SetLocalDevice(localDevice) : CAST_ENGINE_ERROR;
151 }
152
CreateCastSession(const CastSessionProperty &property, std::shared_ptr<ICastSession> &castSession)153 int32_t CastSessionManager::CreateCastSession(const CastSessionProperty &property,
154 std::shared_ptr<ICastSession> &castSession)
155 {
156 CLOGI("in");
157 auto adaptor = GetAdaptor();
158 return adaptor ? adaptor->CreateCastSession(property, castSession) : CAST_ENGINE_ERROR;
159 }
160
SetSinkSessionCapacity(int sessionCapacity)161 int32_t CastSessionManager::SetSinkSessionCapacity(int sessionCapacity)
162 {
163 CLOGD("in");
164 auto adaptor = GetAdaptor();
165 return adaptor ? adaptor->SetSinkSessionCapacity(sessionCapacity) : CAST_ENGINE_ERROR;
166 }
167
StartDiscovery(int protocols)168 int32_t CastSessionManager::StartDiscovery(int protocols)
169 {
170 CLOGD("in");
171 auto adaptor = GetAdaptor();
172 return adaptor ? adaptor->StartDiscovery(protocols) : CAST_ENGINE_ERROR;
173 }
174
SetDiscoverable(bool enable)175 int32_t CastSessionManager::SetDiscoverable(bool enable)
176 {
177 CLOGI("in");
178 auto adaptor = GetAdaptor();
179 return adaptor ? adaptor->SetDiscoverable(enable) : CAST_ENGINE_ERROR;
180 }
181
StopDiscovery()182 int32_t CastSessionManager::StopDiscovery()
183 {
184 CLOGI("in");
185 auto adaptor = GetAdaptor();
186 return adaptor ? adaptor->StopDiscovery() : CAST_ENGINE_ERROR;
187 }
188
GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession)189 int32_t CastSessionManager::GetCastSession(std::string sessionId, std::shared_ptr<ICastSession> &castSession)
190 {
191 CLOGI("in");
192 auto adaptor = GetAdaptor();
193 return adaptor ? adaptor->GetCastSession(sessionId, castSession) : CAST_ENGINE_ERROR;
194 }
195
ReleaseClientResources()196 void CastSessionManager::ReleaseClientResources()
197 {
198 CLOGD("Release client resources");
199 std::lock_guard<std::mutex> lock(mutex_);
200 std::shared_ptr<ICastSessionManagerListener> listener;
201 {
202 if (!!deathRecipient_) {
203 listener = deathRecipient_->GetListener();
204 }
205 deathRecipient_ = nullptr;
206 adaptor_ = nullptr;
207 }
208 if (listener) {
209 listener->OnServiceDied();
210 } else {
211 CLOGE("Report is nullptr");
212 }
213 }
214
ReleaseServiceDeathRecipient()215 void CastSessionManager::ReleaseServiceDeathRecipient()
216 {
217 std::lock_guard<std::mutex> lock(mutex_);
218 deathRecipient_ = nullptr;
219 }
220
OnRemoteDied(const wptr<IRemoteObject> &object)221 void CastSessionManager::CastEngineServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
222 {
223 CLOGE("Service died, need release resources");
224 CastSessionManager::GetInstance().ReleaseClientResources();
225 }
226 } // namespace CastEngineClient
227 } // namespace CastEngine
228 } // namespace OHOS
229