• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "hcamera_host_manager.h"
17 
18 #include "v1_0/icamera_host_callback.h"
19 #include "metadata_utils.h"
20 #include "camera_util.h"
21 #include "hdf_io_service_if.h"
22 #include "iproxy_broker.h"
23 #include "iservmgr_hdi.h"
24 #include "camera_log.h"
25 
26 namespace OHOS {
27 namespace CameraStandard {
28 struct HCameraHostManager::CameraDeviceInfo {
29     std::string cameraId;
30     std::shared_ptr<OHOS::Camera::CameraMetadata> ability;
31     std::mutex mutex;
32 
CameraDeviceInfoOHOS::CameraStandard::HCameraHostManager::CameraDeviceInfo33     explicit CameraDeviceInfo(const std::string& cameraId, sptr<ICameraDevice> device = nullptr)
34         : cameraId(cameraId), ability(nullptr)
35     {
36     }
37 
38     ~CameraDeviceInfo() = default;
39 };
40 
41 class HCameraHostManager::CameraHostInfo : public ICameraHostCallback {
42 public:
43     class CameraHostDeathRecipient : public IRemoteObject::DeathRecipient {
44     public:
CameraHostDeathRecipient(const sptr<HCameraHostManager::CameraHostInfo> & hostInfo)45         explicit CameraHostDeathRecipient(const sptr<HCameraHostManager::CameraHostInfo> &hostInfo) :
46             cameraHostInfo_(hostInfo) {};
47         virtual ~CameraHostDeathRecipient() = default;
OnRemoteDied(const wptr<IRemoteObject> & remote)48         void OnRemoteDied(const wptr<IRemoteObject> &remote) override
49         {
50             MEDIA_ERR_LOG("Remote died, do clean works.");
51             if (cameraHostInfo_ == nullptr) {
52                 return;
53             }
54             cameraHostInfo_->CameraHostDied();
55         }
56 
57     private:
58         sptr<HCameraHostManager::CameraHostInfo> cameraHostInfo_;
59     };
60 
61     explicit CameraHostInfo(HCameraHostManager* cameraHostManager, std::string name);
62     ~CameraHostInfo();
63     bool Init();
64     void CameraHostDied();
65     bool IsCameraSupported(const std::string& cameraId);
66     const std::string& GetName();
67     int32_t GetCameras(std::vector<std::string>& cameraIds);
68     int32_t GetCameraAbility(std::string& cameraId, std::shared_ptr<OHOS::Camera::CameraMetadata>& ability);
69     int32_t OpenCamera(std::string& cameraId, const sptr<ICameraDeviceCallback>& callback,
70                        sptr<ICameraDevice>& pDevice);
71     int32_t SetFlashlight(const std::string& cameraId, bool isEnable);
72 
73     // CameraHostCallbackStub
74     int32_t OnCameraStatus(const std::string& cameraId, HDI::Camera::V1_0::CameraStatus status) override;
75     int32_t OnFlashlightStatus(const std::string& cameraId, FlashlightStatus status) override;
76     int32_t OnCameraEvent(const std::string &cameraId, CameraEvent event) override;
77 
78 private:
79     std::shared_ptr<CameraDeviceInfo> FindCameraDeviceInfo(const std::string& cameraId);
80     void AddDevice(const std::string& cameraId);
81     void RemoveDevice(const std::string& cameraId);
82 
83     HCameraHostManager* cameraHostManager_;
84     std::string name_;
85     sptr<ICameraHost> cameraHostProxy_;
86 
87     std::mutex mutex_;
88     std::vector<std::string> cameraIds_;
89     std::vector<std::shared_ptr<CameraDeviceInfo>> devices_;
90 };
91 
CameraHostInfo(HCameraHostManager * cameraHostManager,std::string name)92 HCameraHostManager::CameraHostInfo::CameraHostInfo(HCameraHostManager* cameraHostManager, std::string name)
93     : cameraHostManager_(cameraHostManager), name_(std::move(name)), cameraHostProxy_(nullptr)
94 {
95 }
96 
~CameraHostInfo()97 HCameraHostManager::CameraHostInfo::~CameraHostInfo()
98 {
99     MEDIA_INFO_LOG("CameraHostInfo ~CameraHostInfo");
100     cameraHostManager_ = nullptr;
101     cameraHostProxy_ = nullptr;
102     for (unsigned i = 0; i < devices_.size(); i++) {
103         devices_[i] = nullptr;
104     }
105     devices_.clear();
106 }
107 
Init()108 bool HCameraHostManager::CameraHostInfo::Init()
109 {
110     if (cameraHostProxy_ != nullptr) {
111         MEDIA_ERR_LOG("CameraHostInfo::Init, no camera host proxy");
112         return true;
113     }
114     cameraHostProxy_ = ICameraHost::Get(name_.c_str(), false);
115     if (cameraHostProxy_ == nullptr) {
116         MEDIA_ERR_LOG("Failed to get ICameraHost");
117         return false;
118     }
119     cameraHostProxy_->SetCallback(this);
120     sptr<CameraHostDeathRecipient> cameraHostDeathRecipient = new CameraHostDeathRecipient(this);
121     const sptr<IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ICameraHost>(cameraHostProxy_);
122     bool result = remote->AddDeathRecipient(cameraHostDeathRecipient);
123     if (!result) {
124         MEDIA_ERR_LOG("AddDeathRecipient for CameraHost failed.");
125     }
126 
127     std::lock_guard<std::mutex> lock(mutex_);
128     CamRetCode ret = (CamRetCode)(cameraHostProxy_->GetCameraIds(cameraIds_));
129     if (ret != HDI::Camera::V1_0::NO_ERROR) {
130         MEDIA_ERR_LOG("Init, GetCameraIds failed, ret = %{public}d", ret);
131         return false;
132     }
133     for (const auto& cameraId : cameraIds_) {
134         devices_.push_back(std::make_shared<HCameraHostManager::CameraDeviceInfo>(cameraId));
135     }
136     return true;
137 }
138 
CameraHostDied()139 void HCameraHostManager::CameraHostInfo::CameraHostDied()
140 {
141     if (cameraHostManager_ == nullptr) {
142         MEDIA_ERR_LOG("CameraHostInfo::cameraHostManager is null.");
143         return;
144     }
145     cameraHostManager_->RemoveCameraHost(name_);
146 }
147 
IsCameraSupported(const std::string & cameraId)148 bool HCameraHostManager::CameraHostInfo::IsCameraSupported(const std::string& cameraId)
149 {
150     std::lock_guard<std::mutex> lock(mutex_);
151     return std::any_of(cameraIds_.begin(), cameraIds_.end(),
152                        [&cameraId](const auto& camId) { return camId == cameraId; });
153 }
154 
GetName()155 const std::string& HCameraHostManager::CameraHostInfo::GetName()
156 {
157     return name_;
158 }
159 
GetCameras(std::vector<std::string> & cameraIds)160 int32_t HCameraHostManager::CameraHostInfo::GetCameras(std::vector<std::string>& cameraIds)
161 {
162     std::lock_guard<std::mutex> lock(mutex_);
163     cameraIds.insert(cameraIds.end(), cameraIds_.begin(), cameraIds_.end());
164     return CAMERA_OK;
165 }
166 
GetCameraAbility(std::string & cameraId,std::shared_ptr<OHOS::Camera::CameraMetadata> & ability)167 int32_t HCameraHostManager::CameraHostInfo::GetCameraAbility(std::string& cameraId,
168     std::shared_ptr<OHOS::Camera::CameraMetadata>& ability)
169 {
170     auto deviceInfo = FindCameraDeviceInfo(cameraId);
171     if (deviceInfo == nullptr) {
172         MEDIA_ERR_LOG("CameraHostInfo::GetCameraAbility deviceInfo is null");
173         return CAMERA_UNKNOWN_ERROR;
174     }
175 
176     std::lock_guard<std::mutex> lock(deviceInfo->mutex);
177     if (deviceInfo->ability) {
178         ability = deviceInfo->ability;
179     } else {
180         if (cameraHostProxy_ == nullptr) {
181             MEDIA_ERR_LOG("CameraHostInfo::GetCameraAbility cameraHostProxy_ is null");
182             return CAMERA_UNKNOWN_ERROR;
183         }
184         if (!deviceInfo->ability) {
185             std::vector<uint8_t> cameraAbility;
186             CamRetCode rc = (CamRetCode)(cameraHostProxy_->GetCameraAbility(cameraId, cameraAbility));
187             if (rc != HDI::Camera::V1_0::NO_ERROR) {
188                 MEDIA_ERR_LOG("CameraHostInfo::GetCameraAbility failed with error Code:%{public}d", rc);
189                 return HdiToServiceError(rc);
190             }
191             OHOS::Camera::MetadataUtils::ConvertVecToMetadata(cameraAbility, ability);
192             deviceInfo->ability = ability;
193         }
194     }
195     return CAMERA_OK;
196 }
197 
OpenCamera(std::string & cameraId,const sptr<ICameraDeviceCallback> & callback,sptr<ICameraDevice> & pDevice)198 int32_t HCameraHostManager::CameraHostInfo::OpenCamera(std::string& cameraId,
199     const sptr<ICameraDeviceCallback>& callback,
200     sptr<ICameraDevice>& pDevice)
201 {
202     MEDIA_INFO_LOG("CameraHostInfo::OpenCamera %{public}s", cameraId.c_str());
203     auto deviceInfo = FindCameraDeviceInfo(cameraId);
204     if (deviceInfo == nullptr) {
205         MEDIA_ERR_LOG("CameraHostInfo::GetCameraAbility deviceInfo is null");
206         return CAMERA_UNKNOWN_ERROR;
207     }
208 
209     std::lock_guard<std::mutex> lock(deviceInfo->mutex);
210     if (cameraHostProxy_ == nullptr) {
211         MEDIA_ERR_LOG("CameraHostInfo::OpenCamera cameraHostProxy_ is null");
212         return CAMERA_UNKNOWN_ERROR;
213     }
214     CamRetCode rc = (CamRetCode)(cameraHostProxy_->OpenCamera(cameraId, callback, pDevice));
215     if (rc != HDI::Camera::V1_0::NO_ERROR) {
216         MEDIA_ERR_LOG("CameraHostInfo::OpenCamera failed with error Code:%{public}d", rc);
217         return HdiToServiceError(rc);
218     }
219     return CAMERA_OK;
220 }
221 
SetFlashlight(const std::string & cameraId,bool isEnable)222 int32_t HCameraHostManager::CameraHostInfo::SetFlashlight(const std::string& cameraId, bool isEnable)
223 {
224     std::lock_guard<std::mutex> lock(mutex_);
225     if (cameraHostProxy_ == nullptr) {
226         MEDIA_ERR_LOG("CameraHostInfo::SetFlashlight cameraHostProxy_ is null");
227         return CAMERA_UNKNOWN_ERROR;
228     }
229     CamRetCode rc = (CamRetCode)(cameraHostProxy_->SetFlashlight(cameraId, isEnable));
230     if (rc != HDI::Camera::V1_0::NO_ERROR) {
231         MEDIA_ERR_LOG("CameraHostInfo::SetFlashlight failed with error Code:%{public}d", rc);
232         return HdiToServiceError(rc);
233     }
234     return CAMERA_OK;
235 }
236 
OnCameraStatus(const std::string & cameraId,HDI::Camera::V1_0::CameraStatus status)237 int32_t HCameraHostManager::CameraHostInfo::OnCameraStatus(const std::string& cameraId,
238                                                            HDI::Camera::V1_0::CameraStatus status)
239 {
240     if ((cameraHostManager_ == nullptr) || (cameraHostManager_->statusCallback_ == nullptr)) {
241         MEDIA_WARNING_LOG("CameraHostInfo::OnCameraStatus for %{public}s with status %{public}d "
242                           "failed due to no callback",
243                           cameraId.c_str(), status);
244         return CAMERA_UNKNOWN_ERROR;
245     }
246     CameraStatus svcStatus = CAMERA_STATUS_UNAVAILABLE;
247     switch (status) {
248         case UN_AVAILABLE: {
249             MEDIA_INFO_LOG("CameraHostInfo::OnCameraStatus, camera %{public}s unavailable", cameraId.c_str());
250             svcStatus = CAMERA_STATUS_UNAVAILABLE;
251             break;
252         }
253         case AVAILABLE: {
254             MEDIA_INFO_LOG("CameraHostInfo::OnCameraStatus, camera %{public}s available", cameraId.c_str());
255             svcStatus = CAMERA_STATUS_AVAILABLE;
256             AddDevice(cameraId);
257             break;
258         }
259         default:
260             MEDIA_ERR_LOG("Unknown camera status: %{public}d", status);
261             return CAMERA_UNKNOWN_ERROR;
262     }
263     cameraHostManager_->statusCallback_->OnCameraStatus(cameraId, svcStatus);
264     return CAMERA_OK;
265 }
266 
OnFlashlightStatus(const std::string & cameraId,FlashlightStatus status)267 int32_t HCameraHostManager::CameraHostInfo::OnFlashlightStatus(const std::string& cameraId,
268     FlashlightStatus status)
269 {
270     if ((cameraHostManager_ == nullptr) || (cameraHostManager_->statusCallback_ == nullptr)) {
271         MEDIA_WARNING_LOG("CameraHostInfo::OnFlashlightStatus for %{public}s with status %{public}d "
272                           "failed due to no callback or cameraHostManager_ is null",
273                           cameraId.c_str(), status);
274         return CAMERA_UNKNOWN_ERROR;
275     }
276     FlashStatus flashStatus = FLASH_STATUS_OFF;
277     switch (status) {
278         case FLASHLIGHT_OFF:
279             flashStatus = FLASH_STATUS_OFF;
280             MEDIA_INFO_LOG("CameraHostInfo::OnFlashlightStatus, camera %{public}s flash light is off",
281                            cameraId.c_str());
282             break;
283 
284         case FLASHLIGHT_ON:
285             flashStatus = FLASH_STATUS_ON;
286             MEDIA_INFO_LOG("CameraHostInfo::OnFlashlightStatus, camera %{public}s flash light is on",
287                            cameraId.c_str());
288             break;
289 
290         case FLASHLIGHT_UNAVAILABLE:
291             flashStatus = FLASH_STATUS_UNAVAILABLE;
292             MEDIA_INFO_LOG("CameraHostInfo::OnFlashlightStatus, camera %{public}s flash light is unavailable",
293                            cameraId.c_str());
294             break;
295 
296         default:
297             MEDIA_ERR_LOG("Unknown flashlight status: %{public}d for camera %{public}s", status, cameraId.c_str());
298             return CAMERA_UNKNOWN_ERROR;
299     }
300     cameraHostManager_->statusCallback_->OnFlashlightStatus(cameraId, flashStatus);
301     return CAMERA_OK;
302 }
303 
OnCameraEvent(const std::string & cameraId,CameraEvent event)304 int32_t HCameraHostManager::CameraHostInfo::OnCameraEvent(const std::string &cameraId, CameraEvent event)
305 {
306     if ((cameraHostManager_ == nullptr) || (cameraHostManager_->statusCallback_ == nullptr)) {
307         MEDIA_WARNING_LOG("CameraHostInfo::OnCameraEvent for %{public}s with status %{public}d "
308                           "failed due to no callback or cameraHostManager_ is null",
309                           cameraId.c_str(), event);
310         return CAMERA_UNKNOWN_ERROR;
311     }
312     CameraStatus svcStatus = CAMERA_STATUS_UNAVAILABLE;
313     switch (event) {
314         case CAMERA_EVENT_DEVICE_RMV: {
315             MEDIA_INFO_LOG("CameraHostInfo::OnCameraEvent, camera %{public}s unavailable", cameraId.c_str());
316             svcStatus = CAMERA_STATUS_UNAVAILABLE;
317             RemoveDevice(cameraId);
318             break;
319         }
320         case CAMERA_EVENT_DEVICE_ADD: {
321             MEDIA_INFO_LOG("CameraHostInfo::OnCameraEvent camera %{public}s available", cameraId.c_str());
322             svcStatus = CAMERA_STATUS_AVAILABLE;
323             AddDevice(cameraId);
324             break;
325         }
326         default:
327             MEDIA_ERR_LOG("Unknown camera event: %{public}d", event);
328             return CAMERA_UNKNOWN_ERROR;
329     }
330     cameraHostManager_->statusCallback_->OnCameraStatus(cameraId, svcStatus);
331     return CAMERA_OK;
332 }
333 
FindCameraDeviceInfo(const std::string & cameraId)334 std::shared_ptr<HCameraHostManager::CameraDeviceInfo> HCameraHostManager::CameraHostInfo::FindCameraDeviceInfo
335    (const std::string& cameraId)
336 {
337     std::lock_guard<std::mutex> lock(mutex_);
338     for (const auto& deviceInfo : devices_) {
339         if (deviceInfo->cameraId == cameraId) {
340             MEDIA_INFO_LOG("CameraHostInfo::FindCameraDeviceInfo succeed for %{public}s", cameraId.c_str());
341             return deviceInfo;
342         }
343     }
344     MEDIA_WARNING_LOG("CameraHostInfo::FindCameraDeviceInfo failed for %{public}s", cameraId.c_str());
345     return nullptr;
346 }
347 
AddDevice(const std::string & cameraId)348 void HCameraHostManager::CameraHostInfo::AddDevice(const std::string& cameraId)
349 {
350     std::lock_guard<std::mutex> lock(mutex_);
351     cameraIds_.push_back(cameraId);
352     if (std::none_of(devices_.begin(), devices_.end(),
353                      [&cameraId](auto& devInfo) { return devInfo->cameraId == cameraId; })) {
354         devices_.push_back(std::make_shared<HCameraHostManager::CameraDeviceInfo>(cameraId));
355         MEDIA_INFO_LOG("CameraHostInfo::AddDevice, camera %{public}s added", cameraId.c_str());
356     } else {
357         MEDIA_WARNING_LOG("CameraHostInfo::AddDevice, camera %{public}s already exists", cameraId.c_str());
358     }
359 }
360 
RemoveDevice(const std::string & cameraId)361 void HCameraHostManager::CameraHostInfo::RemoveDevice(const std::string& cameraId)
362 {
363     std::lock_guard<std::mutex> lock(mutex_);
364     cameraIds_.erase(std::remove(cameraIds_.begin(), cameraIds_.end(), cameraId), cameraIds_.end());
365     devices_.erase(std::remove_if(devices_.begin(), devices_.end(),
366         [&cameraId](const auto& devInfo) { return devInfo->cameraId == cameraId; }),
367         devices_.end());
368 }
369 
HCameraHostManager(StatusCallback * statusCallback)370 HCameraHostManager::HCameraHostManager(StatusCallback* statusCallback)
371     : statusCallback_(statusCallback), cameraHostInfos_()
372 {
373 }
374 
~HCameraHostManager()375 HCameraHostManager::~HCameraHostManager()
376 {
377     statusCallback_ = nullptr;
378     for (auto it = cameraDevices_.begin(); it != cameraDevices_.end(); it++) {
379         if (it->second) {
380             it->second = nullptr;
381         }
382     }
383     cameraDevices_.clear();
384 
385     for (unsigned i = 0; i < cameraHostInfos_.size(); i++) {
386         cameraHostInfos_[i] = nullptr;
387     }
388     cameraHostInfos_.clear();
389 }
390 
Init()391 int32_t HCameraHostManager::Init()
392 {
393     MEDIA_INFO_LOG("HCameraHostManager::Init");
394     using namespace OHOS::HDI::ServiceManager::V1_0;
395     auto svcMgr = IServiceManager::Get();
396     if (svcMgr == nullptr) {
397         MEDIA_ERR_LOG("%s: IServiceManager failed!", __func__);
398         return CAMERA_UNKNOWN_ERROR;
399     }
400     auto rt = svcMgr->RegisterServiceStatusListener(this, DEVICE_CLASS_CAMERA);
401     if (rt != 0) {
402         MEDIA_ERR_LOG("%s: RegisterServiceStatusListener failed!", __func__);
403     }
404     return rt == 0 ? CAMERA_OK : CAMERA_UNKNOWN_ERROR;
405 }
406 
DeInit()407 void HCameraHostManager::DeInit()
408 {
409     using namespace OHOS::HDI::ServiceManager::V1_0;
410     auto svcMgr = IServiceManager::Get();
411     if (svcMgr == nullptr) {
412         MEDIA_ERR_LOG("%s: IServiceManager failed", __func__);
413         return;
414     }
415     auto rt = svcMgr->UnregisterServiceStatusListener(this);
416     if (rt != 0) {
417         MEDIA_ERR_LOG("%s: UnregisterServiceStatusListener failed!", __func__);
418     }
419 }
420 
AddCameraDevice(const std::string & cameraId,sptr<ICameraDeviceService> cameraDevice)421 void HCameraHostManager::AddCameraDevice(const std::string& cameraId, sptr<ICameraDeviceService> cameraDevice)
422 {
423     std::lock_guard<std::mutex> lock(deviceMutex_);
424     cameraDevices_[cameraId] = cameraDevice;
425 }
426 
RemoveCameraDevice(const std::string & cameraId)427 void HCameraHostManager::RemoveCameraDevice(const std::string& cameraId)
428 {
429     std::lock_guard<std::mutex> lock(deviceMutex_);
430     auto it = cameraDevices_.find(cameraId);
431     if (it != cameraDevices_.end()) {
432         it->second = nullptr;
433     }
434     cameraDevices_.erase(cameraId);
435 }
436 
CloseCameraDevice(const std::string & cameraId)437 void HCameraHostManager::CloseCameraDevice(const std::string& cameraId)
438 {
439     sptr<ICameraDeviceService> deviceToDisconnect = nullptr;
440     {
441         std::lock_guard<std::mutex> lock(deviceMutex_);
442         auto iter = cameraDevices_.find(cameraId);
443         if (iter != cameraDevices_.end()) {
444             deviceToDisconnect = iter->second;
445         }
446     }
447     if (deviceToDisconnect) {
448         deviceToDisconnect->Close();
449     }
450 }
451 
GetCameras(std::vector<std::string> & cameraIds)452 int32_t HCameraHostManager::GetCameras(std::vector<std::string>& cameraIds)
453 {
454     CAMERA_SYNC_TRACE;
455     MEDIA_INFO_LOG("HCameraHostManager::GetCameras");
456     if (!IsCameraHostInfoAdded("camera_service")) {
457         AddCameraHost("camera_service");
458     }
459     std::lock_guard<std::mutex> lock(mutex_);
460     cameraIds.clear();
461     for (const auto& cameraHost : cameraHostInfos_) {
462         cameraHost->GetCameras(cameraIds);
463     }
464     return CAMERA_OK;
465 }
466 
GetCameraAbility(std::string & cameraId,std::shared_ptr<OHOS::Camera::CameraMetadata> & ability)467 int32_t HCameraHostManager::GetCameraAbility(std::string &cameraId,
468                                              std::shared_ptr<OHOS::Camera::CameraMetadata> &ability)
469 {
470     auto cameraHostInfo = FindCameraHostInfo(cameraId);
471     if (cameraHostInfo == nullptr) {
472         MEDIA_ERR_LOG("HCameraHostManager::OpenCameraDevice failed with invalid device info.");
473         return CAMERA_INVALID_ARG;
474     }
475     return cameraHostInfo->GetCameraAbility(cameraId, ability);
476 }
477 
CameraConflictDetection(const std::string & cameraId)478 std::vector<sptr<ICameraDeviceService>> HCameraHostManager::CameraConflictDetection(const std::string& cameraId)
479 {
480     std::vector<sptr<ICameraDeviceService>> devicesNeedClose;
481     {
482         std::lock_guard<std::mutex> lock(deviceMutex_);
483         for (auto it = cameraDevices_.begin(); it != cameraDevices_.end(); it++) {
484             if (it->second != nullptr) {
485                 if (it->first == cameraId) {
486                     MEDIA_INFO_LOG("HCameraHostManager::CameraConflictDetection current camera [%{public}s] has Opened,"
487                                    "need close", it->first.c_str());
488                 } else {
489                     MEDIA_INFO_LOG("HCameraHostManager::CameraConflictDetection other camera [%{public}s] has Opened,"
490                                    "need close", it->first.c_str());
491                 }
492                 devicesNeedClose.push_back(it->second);
493             } else {
494                 MEDIA_ERR_LOG("HCameraHostManager::CameraConflictDetection cameraDevice [%{public}s] is null",
495                               it->first.c_str());
496             }
497         }
498     }
499     return devicesNeedClose;
500 }
501 
OpenCameraDevice(std::string & cameraId,const sptr<ICameraDeviceCallback> & callback,sptr<ICameraDevice> & pDevice)502 int32_t HCameraHostManager::OpenCameraDevice(std::string &cameraId,
503                                              const sptr<ICameraDeviceCallback> &callback,
504                                              sptr<ICameraDevice> &pDevice)
505 {
506     MEDIA_INFO_LOG("HCameraHostManager::OpenCameraDevice try to open camera = %{public}s", cameraId.c_str());
507     auto cameraHostInfo = FindCameraHostInfo(cameraId);
508     if (cameraHostInfo == nullptr) {
509         MEDIA_ERR_LOG("HCameraHostManager::OpenCameraDevice failed with invalid device info");
510         return CAMERA_INVALID_ARG;
511     }
512     return cameraHostInfo->OpenCamera(cameraId, callback, pDevice);
513 }
514 
SetFlashlight(const std::string & cameraId,bool isEnable)515 int32_t HCameraHostManager::SetFlashlight(const std::string& cameraId, bool isEnable)
516 {
517     auto cameraHostInfo = FindCameraHostInfo(cameraId);
518     if (cameraHostInfo == nullptr) {
519         MEDIA_ERR_LOG("HCameraHostManager::OpenCameraDevice failed with invalid device info");
520         return CAMERA_INVALID_ARG;
521     }
522     return cameraHostInfo->SetFlashlight(cameraId, isEnable);
523 }
524 
OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus & status)525 void HCameraHostManager::OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus& status)
526 {
527     MEDIA_INFO_LOG("HCameraHostManager::OnReceive for camera host %{public}s, status %{public}d",
528         status.serviceName.c_str(), status.status);
529     if (status.deviceClass != DEVICE_CLASS_CAMERA || status.serviceName != "distributed_camera_service") {
530         MEDIA_ERR_LOG("HCameraHostManager::OnReceive invalid device class %{public}d", status.deviceClass);
531         return;
532     }
533     using namespace OHOS::HDI::ServiceManager::V1_0;
534     switch (status.status) {
535         case SERVIE_STATUS_START:
536             AddCameraHost(status.serviceName);
537             break;
538         case SERVIE_STATUS_STOP:
539             RemoveCameraHost(status.serviceName);
540             break;
541         default:
542             MEDIA_ERR_LOG("HCameraHostManager::OnReceive unexpected service status %{public}d", status.status);
543     }
544 }
545 
AddCameraHost(const std::string & svcName)546 void HCameraHostManager::AddCameraHost(const std::string& svcName)
547 {
548     MEDIA_INFO_LOG("HCameraHostManager::AddCameraHost camera host %{public}s added", svcName.c_str());
549     std::lock_guard<std::mutex> lock(mutex_);
550     if (std::any_of(cameraHostInfos_.begin(), cameraHostInfos_.end(),
551                     [&svcName](const auto& camHost) { return camHost->GetName() == svcName; })) {
552         MEDIA_INFO_LOG("HCameraHostManager::AddCameraHost camera host  %{public}s already exists", svcName.c_str());
553         return;
554     }
555     sptr<HCameraHostManager::CameraHostInfo> cameraHost = new(std::nothrow) HCameraHostManager::CameraHostInfo
556                                                           (this, svcName);
557     if (!cameraHost->Init()) {
558         MEDIA_ERR_LOG("HCameraHostManager::AddCameraHost failed due to init failure");
559         return;
560     }
561     cameraHostInfos_.push_back(cameraHost);
562     std::vector<std::string> cameraIds;
563     if (statusCallback_ && cameraHost->GetCameras(cameraIds) == CAMERA_OK) {
564         for (const auto& cameraId : cameraIds) {
565             statusCallback_->OnCameraStatus(cameraId, CAMERA_STATUS_AVAILABLE);
566         }
567     }
568 }
569 
RemoveCameraHost(const std::string & svcName)570 void HCameraHostManager::RemoveCameraHost(const std::string& svcName)
571 {
572     MEDIA_INFO_LOG("HCameraHostManager::RemoveCameraHost camera host %{public}s removed", svcName.c_str());
573     std::lock_guard<std::mutex> lock(mutex_);
574     auto it = std::find_if(cameraHostInfos_.begin(), cameraHostInfos_.end(),
575                            [&svcName](const auto& camHost) { return camHost->GetName() == svcName; });
576     if (it == cameraHostInfos_.end()) {
577         MEDIA_WARNING_LOG("HCameraHostManager::RemoveCameraHost camera host %{public}s doesn't exist", svcName.c_str());
578         return;
579     }
580     std::vector<std::string> cameraIds;
581     if ((*it)->GetCameras(cameraIds) == CAMERA_OK) {
582         for (const auto& cameraId : cameraIds) {
583             (*it)->OnCameraStatus(cameraId, UN_AVAILABLE);
584             CloseCameraDevice(cameraId);
585         }
586     }
587     *it = nullptr;
588     cameraHostInfos_.erase(it);
589 }
590 
FindCameraHostInfo(const std::string & cameraId)591 sptr<HCameraHostManager::CameraHostInfo> HCameraHostManager::FindCameraHostInfo(const std::string& cameraId)
592 {
593     std::lock_guard<std::mutex> lock(mutex_);
594     for (const auto& cameraHostInfo : cameraHostInfos_) {
595         if (cameraHostInfo->IsCameraSupported(cameraId)) {
596             return cameraHostInfo;
597         }
598     }
599     return nullptr;
600 }
601 
IsCameraHostInfoAdded(const std::string & svcName)602 bool HCameraHostManager::IsCameraHostInfoAdded(const std::string& svcName)
603 {
604     return std::any_of(cameraHostInfos_.begin(), cameraHostInfos_.end(), [&svcName](const auto& camHost) {
605         return camHost->GetName() == svcName; });
606 }
607 } // namespace CameraStandard
608 } // namespace OHOS
609