1 /*
2 * Copyright (c) 2021-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 "distributed_camera_sink_service.h"
17
18 #include "icamera_channel_listener.h"
19 #include "if_system_ability_manager.h"
20 #include "ipc_skeleton.h"
21 #include "ipc_types.h"
22 #include "iservice_registry.h"
23 #include "string_ex.h"
24 #include "system_ability_definition.h"
25
26 #include "anonymous_string.h"
27 #include "dcamera_handler.h"
28 #include "dcamera_hisysevent_adapter.h"
29 #include "dcamera_sink_service_ipc.h"
30 #include "distributed_camera_allconnect_manager.h"
31 #include "distributed_camera_errno.h"
32 #include "distributed_hardware_log.h"
33
34 namespace OHOS {
35 namespace DistributedHardware {
36 REGISTER_SYSTEM_ABILITY_BY_ID(DistributedCameraSinkService, DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID, true);
37
38 static CameraDumpInfo g_camDump;
39 DistributedCameraSinkService* DistributedCameraSinkService::dcSinkService;
DistributedCameraSinkService(int32_t saId,bool runOnCreate)40 DistributedCameraSinkService::DistributedCameraSinkService(int32_t saId, bool runOnCreate)
41 : SystemAbility(saId, runOnCreate)
42 {
43 dcSinkService = this;
44 }
45
OnStart()46 void DistributedCameraSinkService::OnStart()
47 {
48 DHLOGI("DistributedCameraSinkService OnStart");
49 CHECK_AND_RETURN_LOG(state_ == DCameraServiceState::DCAMERA_SRV_STATE_RUNNING,
50 "sink service has already started.");
51
52 if (!Init()) {
53 DHLOGE("DistributedCameraSinkService init failed");
54 return;
55 }
56 state_ = DCameraServiceState::DCAMERA_SRV_STATE_RUNNING;
57 if (!DCameraAllConnectManager::IsInited()) {
58 DCameraAllConnectManager::GetInstance().InitDCameraAllConnectManager();
59 }
60 DHLOGI("DCameraServiceState OnStart service success.");
61 }
62
Init()63 bool DistributedCameraSinkService::Init()
64 {
65 DHLOGI("DistributedCameraSinkService start init");
66 DCameraSinkServiceIpc::GetInstance().Init();
67 if (!registerToService_) {
68 bool ret = Publish(this);
69 CHECK_AND_RETURN_RET_LOG(!ret, false, "Publish service failed");
70 registerToService_ = true;
71 }
72 DHLOGI("DistributedCameraSinkService init success");
73 return true;
74 }
75
OnStop()76 void DistributedCameraSinkService::OnStop()
77 {
78 DHLOGI("DistributedCameraSinkService OnStop service");
79 state_ = DCameraServiceState::DCAMERA_SRV_STATE_NOT_START;
80 registerToService_ = false;
81 if (DCameraAllConnectManager::IsInited()) {
82 DCameraAllConnectManager::GetInstance().UnInitDCameraAllConnectManager();
83 }
84 DCameraSinkServiceIpc::GetInstance().UnInit();
85 }
86
InitSink(const std::string & params,const sptr<IDCameraSinkCallback> & sinkCallback)87 int32_t DistributedCameraSinkService::InitSink(const std::string& params,
88 const sptr<IDCameraSinkCallback> &sinkCallback)
89 {
90 DHLOGI("start");
91 sinkVer_ = params;
92 g_camDump.version = sinkVer_;
93 int32_t ret = DCameraHandler::GetInstance().Initialize();
94 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "handler initialize failed, ret: %{public}d", ret);
95
96 std::vector<std::string> cameras = DCameraHandler::GetInstance().GetCameras();
97 CHECK_AND_RETURN_RET_LOG(cameras.empty(), DCAMERA_BAD_VALUE, "no camera device");
98 g_camDump.camNumber = static_cast<int32_t>(cameras.size());
99 for (auto& dhId : cameras) {
100 std::shared_ptr<DCameraSinkDev> sinkDevice = std::make_shared<DCameraSinkDev>(dhId, sinkCallback);
101 ret = sinkDevice->Init();
102 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "sink device init failed, ret: %{public}d", ret);
103 {
104 std::lock_guard<std::mutex> lock(mapMutex_);
105 camerasMap_.emplace(dhId, sinkDevice);
106 }
107 }
108 DHLOGI("success");
109 return DCAMERA_OK;
110 }
111
ReleaseSink()112 int32_t DistributedCameraSinkService::ReleaseSink()
113 {
114 DHLOGI("enter");
115 {
116 std::lock_guard<std::mutex> lock(mapMutex_);
117 for (auto iter = camerasMap_.begin(); iter != camerasMap_.end(); iter++) {
118 std::shared_ptr<DCameraSinkDev> sinkDevice = iter->second;
119 int32_t ret = sinkDevice->UnInit();
120 CHECK_AND_LOG(ret != DCAMERA_OK, "release sink device failed, ret: %{public}d", ret);
121 }
122 camerasMap_.clear();
123 }
124
125 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
126 CHECK_AND_RETURN_RET_LOG(systemAbilityMgr == nullptr, DCAMERA_BAD_VALUE, "sink systemAbilityMgr is null");
127 int32_t ret = systemAbilityMgr->UnloadSystemAbility(DISTRIBUTED_HARDWARE_CAMERA_SINK_SA_ID);
128 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, DCAMERA_BAD_VALUE,
129 "sink systemAbilityMgr UnLoadSystemAbility failed, ret: %{public}d", ret);
130 DHLOGI("sink systemAbilityMgr UnLoadSystemAbility success");
131 return DCAMERA_OK;
132 }
133
SubscribeLocalHardware(const std::string & dhId,const std::string & parameters)134 int32_t DistributedCameraSinkService::SubscribeLocalHardware(const std::string& dhId, const std::string& parameters)
135 {
136 DHLOGI("dhId: %{public}s", GetAnonyString(dhId).c_str());
137 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
138 {
139 std::lock_guard<std::mutex> lock(mapMutex_);
140 auto iter = camerasMap_.find(dhId);
141 if (iter == camerasMap_.end()) {
142 DHLOGE("device not found");
143 return DCAMERA_NOT_FOUND;
144 }
145 sinkDevice = iter->second;
146 }
147
148 int32_t ret = sinkDevice->SubscribeLocalHardware(parameters);
149 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "SubscribeLocalHardware failed, ret: %{public}d", ret);
150 DHLOGI("SubscribeLocalHardware success");
151 return DCAMERA_OK;
152 }
153
UnsubscribeLocalHardware(const std::string & dhId)154 int32_t DistributedCameraSinkService::UnsubscribeLocalHardware(const std::string& dhId)
155 {
156 DHLOGI("dhId: %{public}s", GetAnonyString(dhId).c_str());
157 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
158 {
159 std::lock_guard<std::mutex> lock(mapMutex_);
160 auto iter = camerasMap_.find(dhId);
161 if (iter == camerasMap_.end()) {
162 DHLOGE("device not found");
163 return DCAMERA_NOT_FOUND;
164 }
165 sinkDevice = iter->second;
166 }
167
168 int32_t ret = sinkDevice->UnsubscribeLocalHardware();
169 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "UnsubscribeLocalHardware failed, ret: %{public}d", ret);
170 DHLOGI("UnsubscribeLocalHardware success");
171 return DCAMERA_OK;
172 }
173
StopCapture(const std::string & dhId)174 int32_t DistributedCameraSinkService::StopCapture(const std::string& dhId)
175 {
176 DHLOGI("dhId: %{public}s", GetAnonyString(dhId).c_str());
177 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
178 {
179 std::lock_guard<std::mutex> lock(mapMutex_);
180 auto iter = camerasMap_.find(dhId);
181 if (iter == camerasMap_.end()) {
182 DHLOGE("device not found");
183 return DCAMERA_NOT_FOUND;
184 }
185 sinkDevice = iter->second;
186 }
187
188 int32_t ret = sinkDevice->StopCapture();
189 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "StopCapture failed, ret: %{public}d", ret);
190 DHLOGI("StopCapture success");
191 return DCAMERA_OK;
192 }
193
ChannelNeg(const std::string & dhId,std::string & channelInfo)194 int32_t DistributedCameraSinkService::ChannelNeg(const std::string& dhId, std::string& channelInfo)
195 {
196 DHLOGI("dhId: %{public}s", GetAnonyString(dhId).c_str());
197 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
198 {
199 std::lock_guard<std::mutex> lock(mapMutex_);
200 auto iter = camerasMap_.find(dhId);
201 if (iter == camerasMap_.end()) {
202 DHLOGE("device not found");
203 return DCAMERA_NOT_FOUND;
204 }
205 sinkDevice = iter->second;
206 }
207
208 int32_t ret = sinkDevice->ChannelNeg(channelInfo);
209 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "ChannelNeg failed, ret: %{public}d", ret);
210 DHLOGI("ChannelNeg success");
211 return DCAMERA_OK;
212 }
213
GetCameraInfo(const std::string & dhId,std::string & cameraInfo)214 int32_t DistributedCameraSinkService::GetCameraInfo(const std::string& dhId, std::string& cameraInfo)
215 {
216 DHLOGI("dhId: %{public}s", GetAnonyString(dhId).c_str());
217 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
218 {
219 std::lock_guard<std::mutex> lock(mapMutex_);
220 auto iter = camerasMap_.find(dhId);
221 if (iter == camerasMap_.end()) {
222 DHLOGE("device not found");
223 return DCAMERA_NOT_FOUND;
224 }
225 sinkDevice = iter->second;
226 }
227
228 int32_t ret = sinkDevice->GetCameraInfo(cameraInfo);
229 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "GetCameraInfo failed, ret: %{public}d", ret);
230 DHLOGI("GetCameraInfo success");
231 return DCAMERA_OK;
232 }
233
OpenChannel(const std::string & dhId,std::string & openInfo)234 int32_t DistributedCameraSinkService::OpenChannel(const std::string& dhId, std::string& openInfo)
235 {
236 DHLOGI("DistributedCameraSinkService OpenChannel Begin, dhId: %{public}s", GetAnonyString(dhId).c_str());
237 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
238 {
239 std::lock_guard<std::mutex> lock(mapMutex_);
240 auto iter = camerasMap_.find(dhId);
241 if (iter == camerasMap_.end()) {
242 DHLOGE("device not found");
243 return DCAMERA_NOT_FOUND;
244 }
245 sinkDevice = iter->second;
246 }
247
248 int32_t ret = sinkDevice->OpenChannel(openInfo);
249 if (ret != DCAMERA_OK) {
250 DHLOGE("OpenChannel failed, ret: %{public}d", ret);
251 ReportDcamerOptFail(DCAMERA_OPT_FAIL, DCAMERA_SINK_OPEN_CAM_ERROR,
252 CreateMsg("sink service open channel failed, dhId: %s", GetAnonyString(dhId).c_str()));
253 return ret;
254 }
255 DHLOGI("DistributedCameraSinkService OpenChannel success");
256 return DCAMERA_OK;
257 }
258
CloseChannel(const std::string & dhId)259 int32_t DistributedCameraSinkService::CloseChannel(const std::string& dhId)
260 {
261 DHLOGI("dhId: %{public}s", GetAnonyString(dhId).c_str());
262 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
263 {
264 std::lock_guard<std::mutex> lock(mapMutex_);
265 auto iter = camerasMap_.find(dhId);
266 if (iter == camerasMap_.end()) {
267 DHLOGE("device not found");
268 return DCAMERA_NOT_FOUND;
269 }
270 sinkDevice = iter->second;
271 }
272
273 int32_t ret = sinkDevice->CloseChannel();
274 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "CloseChannel failed, ret: %{public}d", ret);
275 DHLOGI("CloseChannel success");
276 return DCAMERA_OK;
277 }
278
Dump(int32_t fd,const std::vector<std::u16string> & args)279 int DistributedCameraSinkService::Dump(int32_t fd, const std::vector<std::u16string>& args)
280 {
281 DHLOGI("DistributedCameraSinkService Dump.");
282 if (args.size() > DUMP_MAX_SIZE) {
283 DHLOGE("DistributedCameraSinkService Dump input is invalid");
284 return DCAMERA_BAD_VALUE;
285 }
286 std::string result;
287 std::vector<std::string> argsStr;
288 for (auto item : args) {
289 argsStr.emplace_back(Str16ToStr8(item));
290 }
291
292 if (!DcameraSinkHidumper::GetInstance().Dump(argsStr, result)) {
293 DHLOGE("Hidump error");
294 return DCAMERA_BAD_VALUE;
295 }
296
297 int ret = dprintf(fd, "%s\n", result.c_str());
298 CHECK_AND_RETURN_RET_LOG(ret < 0, DCAMERA_BAD_VALUE, "dprintf error");
299
300 return DCAMERA_OK;
301 }
302
GetCamIds()303 void DistributedCameraSinkService::GetCamIds()
304 {
305 std::vector<std::string> camIds;
306 {
307 std::lock_guard<std::mutex> lock(mapMutex_);
308 for (auto it = camerasMap_.begin(); it != camerasMap_.end(); it++) {
309 camIds.push_back(it->second->GetDhid());
310 }
311 }
312 g_camDump.camIds = camIds;
313 }
314
GetCamDumpInfo(CameraDumpInfo & camDump)315 void DistributedCameraSinkService::GetCamDumpInfo(CameraDumpInfo& camDump)
316 {
317 dcSinkService->GetCamIds();
318 camDump = g_camDump;
319 }
320
IsCurSinkDev(std::shared_ptr<DCameraSinkDev> sinkDevice)321 bool DistributedCameraSinkService::IsCurSinkDev(std::shared_ptr<DCameraSinkDev> sinkDevice)
322 {
323 std::string camInfoJson;
324 CHECK_AND_RETURN_RET_LOG(sinkDevice == nullptr, false, "sinkDevice is null.");
325 int32_t ret = sinkDevice->GetCameraInfo(camInfoJson);
326 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, false, "GetCameraInfo failed, ret: %{public}d", ret);
327 DCameraInfoCmd cmd;
328 ret = cmd.Unmarshal(camInfoJson);
329 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, false, "DCameraInfoCmd Unmarshal failed: %{public}d", ret);
330 std::shared_ptr<DCameraInfo> camInfo = cmd.value_;
331 if (camInfo->state_ == DCAMERA_CHANNEL_STATE_CONNECTED) {
332 return true;
333 }
334 return false;
335 }
336
PauseDistributedHardware(const std::string & networkId)337 int32_t DistributedCameraSinkService::PauseDistributedHardware(const std::string &networkId)
338 {
339 DHLOGI("start.");
340 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
341 {
342 std::lock_guard<std::mutex> lock(mapMutex_);
343 for (auto iter = camerasMap_.begin(); iter != camerasMap_.end(); iter++) {
344 if (IsCurSinkDev(iter->second)) {
345 sinkDevice = iter->second;
346 break;
347 }
348 }
349 }
350 CHECK_AND_RETURN_RET_LOG(sinkDevice == nullptr, DCAMERA_BAD_VALUE,
351 "PauseDistributedHardware sinkDevice is nullptr.");
352
353 int32_t ret = sinkDevice->PauseDistributedHardware(networkId);
354 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "PauseDistributedHardware failed, ret: %{public}d", ret);
355 DHLOGI("PauseDistributedHardware success");
356 return DCAMERA_OK;
357 }
358
ResumeDistributedHardware(const std::string & networkId)359 int32_t DistributedCameraSinkService::ResumeDistributedHardware(const std::string &networkId)
360 {
361 DHLOGI("start.");
362 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
363 {
364 std::lock_guard<std::mutex> lock(mapMutex_);
365 for (auto iter = camerasMap_.begin(); iter != camerasMap_.end(); iter++) {
366 if (IsCurSinkDev(iter->second)) {
367 sinkDevice = iter->second;
368 break;
369 }
370 }
371 }
372 CHECK_AND_RETURN_RET_LOG(sinkDevice == nullptr, DCAMERA_BAD_VALUE,
373 "ResumeDistributedHardware sinkDevice is nullptr.");
374
375 int32_t ret = sinkDevice->ResumeDistributedHardware(networkId);
376 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "ResumeDistributedHardware failed, ret: %{public}d", ret);
377 DHLOGI("ResumeDistributedHardware success");
378 return DCAMERA_OK;
379 }
380
StopDistributedHardware(const std::string & networkId)381 int32_t DistributedCameraSinkService::StopDistributedHardware(const std::string &networkId)
382 {
383 DHLOGI("start.");
384 std::shared_ptr<DCameraSinkDev> sinkDevice = nullptr;
385 {
386 std::lock_guard<std::mutex> lock(mapMutex_);
387 for (auto iter = camerasMap_.begin(); iter != camerasMap_.end(); iter++) {
388 if (IsCurSinkDev(iter->second)) {
389 sinkDevice = iter->second;
390 break;
391 }
392 }
393 }
394 CHECK_AND_RETURN_RET_LOG(sinkDevice == nullptr, DCAMERA_BAD_VALUE,
395 "StopDistributedHardware sinkDevice is nullptr.");
396
397 int32_t ret = sinkDevice->StopDistributedHardware(networkId);
398 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "StopDistributedHardware failed, ret: %{public}d", ret);
399 DHLOGI("StopDistributedHardware success");
400 return DCAMERA_OK;
401 }
402 } // namespace DistributedHardware
403 } // namespace OHOS