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