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