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