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