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