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