• 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 #include "camera_host_callback_stub.h"
18 #include "camera_util.h"
19 #include "hdf_io_service_if.h"
20 #include "iservmgr_hdi.h"
21 #include "media_log.h"
22 
23 namespace OHOS {
24 namespace CameraStandard {
25 struct HCameraHostManager::CameraDeviceInfo {
26     std::string cameraId;
27     std::shared_ptr<Camera::CameraMetadata> ability;
28     std::mutex mutex;
29 
CameraDeviceInfoOHOS::CameraStandard::HCameraHostManager::CameraDeviceInfo30     explicit CameraDeviceInfo(const std::string& cameraId, sptr<Camera::ICameraDevice> device = nullptr)
31         : cameraId(cameraId), ability(nullptr)
32     {
33     }
34 
35     ~CameraDeviceInfo() = default;
36 };
37 
38 class HCameraHostManager::CameraHostInfo : public Camera::CameraHostCallbackStub {
39 public:
40     explicit CameraHostInfo(HCameraHostManager* cameraHostManager, std::string name);
41     ~CameraHostInfo();
42     bool Init();
43     bool IsCameraSupported(const std::string& cameraId);
44     const std::string& GetName();
45     int32_t GetCameras(std::vector<std::string>& cameraIds);
46     int32_t GetCameraAbility(std::string& cameraId, std::shared_ptr<Camera::CameraMetadata>& ability);
47     int32_t OpenCamera(std::string& cameraId, const sptr<Camera::ICameraDeviceCallback>& callback,
48                        sptr<Camera::ICameraDevice>& pDevice);
49     int32_t SetFlashlight(const std::string& cameraId, bool isEnable);
50 
51     // CameraHostCallbackStub
52     void OnCameraStatus(const std::string& cameraId, Camera::CameraStatus status) override;
53     void OnFlashlightStatus(const std::string& cameraId, Camera::FlashlightStatus status) override;
54     void OnCameraEvent(const std::string &cameraId, Camera::CameraEvent event) override;
55 
56 private:
57     std::shared_ptr<CameraDeviceInfo> FindCameraDeviceInfo(const std::string& cameraId);
58     void AddDevice(const std::string& cameraId);
59     void RemoveDevice(const std::string& cameraId);
60 
61     HCameraHostManager* cameraHostManager_;
62     std::string name_;
63     sptr<Camera::ICameraHost> cameraHostProxy_;
64 
65     std::mutex mutex_;
66     std::vector<std::string> cameraIds_;
67     std::vector<std::shared_ptr<CameraDeviceInfo>> devices_;
68 };
69 
CameraHostInfo(HCameraHostManager * cameraHostManager,std::string name)70 HCameraHostManager::CameraHostInfo::CameraHostInfo(HCameraHostManager* cameraHostManager, std::string name)
71     : cameraHostManager_(cameraHostManager), name_(std::move(name)), cameraHostProxy_(nullptr)
72 {
73 }
74 
~CameraHostInfo()75 HCameraHostManager::CameraHostInfo::~CameraHostInfo()
76 {
77     MEDIA_INFO_LOG("CameraHostInfo ~CameraHostInfo");
78 }
79 
Init()80 bool HCameraHostManager::CameraHostInfo::Init()
81 {
82     if (cameraHostProxy_ != nullptr) {
83         MEDIA_ERR_LOG("CameraHostInfo::Init, no camera host proxy");
84         return true;
85     }
86     cameraHostProxy_ = Camera::ICameraHost::Get(name_.c_str());
87     if (cameraHostProxy_ == nullptr) {
88         MEDIA_ERR_LOG("Failed to get ICameraHost");
89         return false;
90     }
91     cameraHostProxy_->SetCallback(this);
92     std::lock_guard<std::mutex> lock(mutex_);
93     Camera::CamRetCode ret = cameraHostProxy_->GetCameraIds(cameraIds_);
94     if (ret != Camera::NO_ERROR) {
95         MEDIA_ERR_LOG("Init, GetCameraIds failed, ret = %{public}d", ret);
96         return false;
97     }
98     for (const auto& cameraId : cameraIds_) {
99         devices_.push_back(std::make_shared<HCameraHostManager::CameraDeviceInfo>(cameraId));
100     }
101     return true;
102 }
103 
IsCameraSupported(const std::string & cameraId)104 bool HCameraHostManager::CameraHostInfo::IsCameraSupported(const std::string& cameraId)
105 {
106     std::lock_guard<std::mutex> lock(mutex_);
107     return std::any_of(cameraIds_.begin(), cameraIds_.end(),
108                        [&cameraId](const auto& camId) { return camId == cameraId; });
109 }
110 
GetName()111 const std::string& HCameraHostManager::CameraHostInfo::GetName()
112 {
113     return name_;
114 }
115 
GetCameras(std::vector<std::string> & cameraIds)116 int32_t HCameraHostManager::CameraHostInfo::GetCameras(std::vector<std::string>& cameraIds)
117 {
118     std::lock_guard<std::mutex> lock(mutex_);
119     cameraIds.insert(cameraIds.end(), cameraIds_.begin(), cameraIds_.end());
120     return CAMERA_OK;
121 }
122 
GetCameraAbility(std::string & cameraId,std::shared_ptr<Camera::CameraMetadata> & ability)123 int32_t HCameraHostManager::CameraHostInfo::GetCameraAbility(std::string& cameraId,
124     std::shared_ptr<Camera::CameraMetadata>& ability)
125 {
126     auto deviceInfo = FindCameraDeviceInfo(cameraId);
127     if (deviceInfo == nullptr) {
128         MEDIA_ERR_LOG("CameraHostInfo::GetCameraAbility deviceInfo is null");
129         return CAMERA_UNKNOWN_ERROR;
130     }
131 
132     if (deviceInfo->ability) {
133         ability = deviceInfo->ability;
134     } else {
135         std::lock_guard<std::mutex> lock(deviceInfo->mutex);
136         if (!deviceInfo->ability) {
137             Camera::CamRetCode rc = cameraHostProxy_->GetCameraAbility(cameraId, ability);
138             if (rc != Camera::NO_ERROR) {
139                 MEDIA_ERR_LOG("CameraHostInfo::GetCameraAbility failed with error Code:%{public}d", rc);
140                 return HdiToServiceError(rc);
141             }
142             deviceInfo->ability = ability;
143         }
144     }
145     return CAMERA_OK;
146 }
147 
OpenCamera(std::string & cameraId,const sptr<Camera::ICameraDeviceCallback> & callback,sptr<Camera::ICameraDevice> & pDevice)148 int32_t HCameraHostManager::CameraHostInfo::OpenCamera(std::string& cameraId,
149     const sptr<Camera::ICameraDeviceCallback>& callback,
150     sptr<Camera::ICameraDevice>& pDevice)
151 {
152     MEDIA_INFO_LOG("CameraHostInfo::OpenCamera %{public}s", cameraId.c_str());
153     auto deviceInfo = FindCameraDeviceInfo(cameraId);
154     if (deviceInfo == nullptr) {
155         MEDIA_ERR_LOG("CameraHostInfo::GetCameraAbility deviceInfo is null");
156         return CAMERA_UNKNOWN_ERROR;
157     }
158 
159     std::lock_guard<std::mutex> lock(deviceInfo->mutex);
160     Camera::CamRetCode rc = cameraHostProxy_->OpenCamera(cameraId, callback, pDevice);
161     if (rc != Camera::NO_ERROR) {
162         MEDIA_ERR_LOG("CameraHostInfo::OpenCamera failed with error Code:%{public}d", rc);
163         return HdiToServiceError(rc);
164     }
165     return CAMERA_OK;
166 }
167 
SetFlashlight(const std::string & cameraId,bool isEnable)168 int32_t HCameraHostManager::CameraHostInfo::SetFlashlight(const std::string& cameraId, bool isEnable)
169 {
170     std::lock_guard<std::mutex> lock(mutex_);
171     Camera::CamRetCode rc = cameraHostProxy_->SetFlashlight(cameraId, isEnable);
172     if (rc != Camera::NO_ERROR) {
173         MEDIA_ERR_LOG("CameraHostInfo::SetFlashlight failed with error Code:%{public}d", rc);
174         return HdiToServiceError(rc);
175     }
176     return CAMERA_OK;
177 }
178 
OnCameraStatus(const std::string & cameraId,Camera::CameraStatus status)179 void HCameraHostManager::CameraHostInfo::OnCameraStatus(const std::string& cameraId, Camera::CameraStatus status)
180 {
181     if (cameraHostManager_->statusCallback_ == nullptr) {
182         MEDIA_WARNING_LOG("CameraHostInfo::OnCameraStatus for %{public}s with status %{public}d "
183                           "failed due to no callback",
184                           cameraId.c_str(), status);
185         return;
186     }
187     CameraStatus svcStatus = CAMERA_STATUS_UNAVAILABLE;
188     switch (status) {
189         case Camera::UN_AVAILABLE: {
190             MEDIA_INFO_LOG("CameraHostInfo::OnCameraStatus, camera %{public}s unavailable", cameraId.c_str());
191             svcStatus = CAMERA_STATUS_UNAVAILABLE;
192             RemoveDevice(cameraId);
193             break;
194         }
195         case Camera::AVAILABLE: {
196             MEDIA_INFO_LOG("CameraHostInfo::OnCameraStatus, camera %{public}s available", cameraId.c_str());
197             svcStatus = CAMERA_STATUS_AVAILABLE;
198             AddDevice(cameraId);
199             break;
200         }
201         default:
202             MEDIA_ERR_LOG("Unknown camera status: %{public}d", status);
203             return;
204     }
205     cameraHostManager_->statusCallback_->OnCameraStatus(cameraId, svcStatus);
206 }
207 
OnFlashlightStatus(const std::string & cameraId,Camera::FlashlightStatus status)208 void HCameraHostManager::CameraHostInfo::OnFlashlightStatus(const std::string& cameraId,
209     Camera::FlashlightStatus status)
210 {
211     if (cameraHostManager_->statusCallback_ == nullptr) {
212         MEDIA_WARNING_LOG("CameraHostInfo::OnFlashlightStatus for %{public}s with status %{public}d "
213                           "failed due to no callback",
214                           cameraId.c_str(), status);
215         return;
216     }
217     FlashStatus flashStatus = FLASH_STATUS_OFF;
218     switch (status) {
219         case Camera::FLASHLIGHT_OFF:
220             flashStatus = FLASH_STATUS_OFF;
221             MEDIA_INFO_LOG("CameraHostInfo::OnFlashlightStatus, camera %{public}s flash light is off",
222                            cameraId.c_str());
223             break;
224 
225         case Camera::FLASHLIGHT_ON:
226             flashStatus = FLASH_STATUS_ON;
227             MEDIA_INFO_LOG("CameraHostInfo::OnFlashlightStatus, camera %{public}s flash light is on",
228                            cameraId.c_str());
229             break;
230 
231         case Camera::FLASHLIGHT_UNAVAILABLE:
232             flashStatus = FLASH_STATUS_UNAVAILABLE;
233             MEDIA_INFO_LOG("CameraHostInfo::OnFlashlightStatus, camera %{public}s flash light is unavailable",
234                            cameraId.c_str());
235             break;
236 
237         default:
238             MEDIA_ERR_LOG("Unknown flashlight status: %{public}d for camera %{public}s", status, cameraId.c_str());
239             return;
240     }
241     cameraHostManager_->statusCallback_->OnFlashlightStatus(cameraId, flashStatus);
242 }
243 
OnCameraEvent(const std::string & cameraId,Camera::CameraEvent event)244 void HCameraHostManager::CameraHostInfo::OnCameraEvent(const std::string &cameraId, Camera::CameraEvent event)
245 {
246     if (cameraHostManager_->statusCallback_ == nullptr) {
247         MEDIA_WARNING_LOG("CameraHostInfo::OnCameraEvent for %{public}s with status %{public}d "
248                           "failed due to no callback",
249                           cameraId.c_str(), event);
250         return;
251     }
252     CameraStatus svcStatus = CAMERA_STATUS_UNAVAILABLE;
253     switch (event) {
254         case Camera::CAMERA_EVENT_DEVICE_RMV: {
255             MEDIA_INFO_LOG("CameraHostInfo::OnCameraEvent, camera %{public}s unavailable", cameraId.c_str());
256             svcStatus = CAMERA_STATUS_UNAVAILABLE;
257             RemoveDevice(cameraId);
258             break;
259         }
260         case Camera::CAMERA_EVENT_DEVICE_ADD: {
261             MEDIA_INFO_LOG("CameraHostInfo::OnCameraEvent camera %{public}s available", cameraId.c_str());
262             svcStatus = CAMERA_STATUS_AVAILABLE;
263             AddDevice(cameraId);
264             break;
265         }
266         default:
267             MEDIA_ERR_LOG("Unknown camera event: %{public}d", event);
268             return;
269     }
270     cameraHostManager_->statusCallback_->OnCameraStatus(cameraId, svcStatus);
271 }
272 
FindCameraDeviceInfo(const std::string & cameraId)273 std::shared_ptr<HCameraHostManager::CameraDeviceInfo> HCameraHostManager::CameraHostInfo::FindCameraDeviceInfo
274    (const std::string& cameraId)
275 {
276     std::lock_guard<std::mutex> lock(mutex_);
277     for (const auto& deviceInfo : devices_) {
278         if (deviceInfo->cameraId == cameraId) {
279             MEDIA_INFO_LOG("CameraHostInfo::FindCameraDeviceInfo succeed for %{public}s", cameraId.c_str());
280             return deviceInfo;
281         }
282     }
283     MEDIA_WARNING_LOG("CameraHostInfo::FindCameraDeviceInfo failed for %{public}s", cameraId.c_str());
284     return nullptr;
285 }
286 
AddDevice(const std::string & cameraId)287 void HCameraHostManager::CameraHostInfo::AddDevice(const std::string& cameraId)
288 {
289     std::lock_guard<std::mutex> lock(mutex_);
290     cameraIds_.push_back(cameraId);
291     if (std::none_of(devices_.begin(), devices_.end(),
292                      [&cameraId](auto& devInfo) { return devInfo->cameraId == cameraId; })) {
293         devices_.push_back(std::make_shared<HCameraHostManager::CameraDeviceInfo>(cameraId));
294         MEDIA_INFO_LOG("CameraHostInfo::AddDevice, camera %{public}s added", cameraId.c_str());
295     } else {
296         MEDIA_WARNING_LOG("CameraHostInfo::AddDevice, camera %{public}s already exists", cameraId.c_str());
297     }
298 }
299 
RemoveDevice(const std::string & cameraId)300 void HCameraHostManager::CameraHostInfo::RemoveDevice(const std::string& cameraId)
301 {
302     std::lock_guard<std::mutex> lock(mutex_);
303     cameraIds_.erase(std::remove(cameraIds_.begin(), cameraIds_.end(), cameraId), cameraIds_.end());
304     devices_.erase(std::remove_if(devices_.begin(), devices_.end(),
305         [&cameraId](const auto& devInfo) { return devInfo->cameraId == cameraId; }),
306         devices_.end());
307 }
308 
HCameraHostManager(StatusCallback * statusCallback)309 HCameraHostManager::HCameraHostManager(StatusCallback* statusCallback)
310     : statusCallback_(statusCallback), cameraHostInfos_()
311 {
312 }
313 
~HCameraHostManager()314 HCameraHostManager::~HCameraHostManager()
315 {
316     statusCallback_ = nullptr;
317 }
318 
Init()319 int32_t HCameraHostManager::Init()
320 {
321     MEDIA_INFO_LOG("HCameraHostManager::Init");
322     using namespace OHOS::HDI::ServiceManager::V1_0;
323     auto svcMgr = IServiceManager::Get();
324     if (svcMgr == nullptr) {
325         MEDIA_ERR_LOG("%s: IServiceManager failed!", __func__);
326         return CAMERA_UNKNOWN_ERROR;
327     }
328     auto rt = svcMgr->RegisterServiceStatusListener(this, DEVICE_CLASS_CAMERA);
329     if (rt != 0) {
330         MEDIA_ERR_LOG("%s: RegisterServiceStatusListener failed!", __func__);
331     }
332     return rt == 0 ? CAMERA_OK : CAMERA_UNKNOWN_ERROR;
333 }
334 
DeInit()335 void HCameraHostManager::DeInit()
336 {
337     using namespace OHOS::HDI::ServiceManager::V1_0;
338     auto svcMgr = IServiceManager::Get();
339     if (svcMgr == nullptr) {
340         MEDIA_ERR_LOG("%s: IServiceManager failed", __func__);
341         return;
342     }
343     auto rt = svcMgr->UnregisterServiceStatusListener(this);
344     if (rt != 0) {
345         MEDIA_ERR_LOG("%s: UnregisterServiceStatusListener failed!", __func__);
346     }
347 }
348 
GetCameras(std::vector<std::string> & cameraIds)349 int32_t HCameraHostManager::GetCameras(std::vector<std::string>& cameraIds)
350 {
351     MEDIA_INFO_LOG("HCameraHostManager::GetCameras");
352     if (cameraHostInfos_.size() == 0) {
353         MEDIA_INFO_LOG("HCameraHostManager::GetCameras host info is empty, start add host");
354         AddCameraHost("camera_service");
355         AddCameraHost("distributed_camera_service");
356     }
357     std::lock_guard<std::mutex> lock(mutex_);
358     cameraIds.clear();
359     for (const auto& cameraHost : cameraHostInfos_) {
360         cameraHost->GetCameras(cameraIds);
361     }
362     return CAMERA_OK;
363 }
364 
GetCameraAbility(std::string & cameraId,std::shared_ptr<Camera::CameraMetadata> & ability)365 int32_t HCameraHostManager::GetCameraAbility(std::string &cameraId,
366                                              std::shared_ptr<Camera::CameraMetadata> &ability)
367 {
368     auto cameraHostInfo = FindCameraHostInfo(cameraId);
369     if (!cameraHostInfo) {
370         MEDIA_ERR_LOG("HCameraHostManager::OpenCameraDevice failed with invalid device info.");
371         return CAMERA_INVALID_ARG;
372     }
373     return cameraHostInfo->GetCameraAbility(cameraId, ability);
374 }
375 
OpenCameraDevice(std::string & cameraId,const sptr<Camera::ICameraDeviceCallback> & callback,sptr<Camera::ICameraDevice> & pDevice)376 int32_t HCameraHostManager::OpenCameraDevice(std::string &cameraId,
377                                              const sptr<Camera::ICameraDeviceCallback> &callback,
378                                              sptr<Camera::ICameraDevice> &pDevice)
379 {
380     auto cameraHostInfo = FindCameraHostInfo(cameraId);
381     if (!cameraHostInfo) {
382         MEDIA_ERR_LOG("HCameraHostManager::OpenCameraDevice failed with invalid device info");
383         return CAMERA_INVALID_ARG;
384     }
385     return cameraHostInfo->OpenCamera(cameraId, callback, pDevice);
386 }
387 
SetFlashlight(const std::string & cameraId,bool isEnable)388 int32_t HCameraHostManager::SetFlashlight(const std::string& cameraId, bool isEnable)
389 {
390     auto cameraHostInfo = FindCameraHostInfo(cameraId);
391     if (!cameraHostInfo) {
392         MEDIA_ERR_LOG("HCameraHostManager::OpenCameraDevice failed with invalid device info");
393         return CAMERA_INVALID_ARG;
394     }
395     return cameraHostInfo->SetFlashlight(cameraId, isEnable);
396 }
397 
OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus & status)398 void HCameraHostManager::OnReceive(const HDI::ServiceManager::V1_0::ServiceStatus& status)
399 {
400     MEDIA_INFO_LOG("HCameraHostManager::OnReceive for camera host %{public}s", status.serviceName.c_str());
401     if (status.deviceClass != DEVICE_CLASS_CAMERA) {
402         MEDIA_ERR_LOG("HCameraHostManager::OnReceive invalid device class %{public}d", status.deviceClass);
403         return;
404     }
405     using namespace OHOS::HDI::ServiceManager::V1_0;
406     std::lock_guard<std::mutex> lock(mutex_);
407     switch (status.status) {
408         case SERVIE_STATUS_START:
409             AddCameraHost(status.serviceName);
410             break;
411         case SERVIE_STATUS_STOP:
412             RemoveCameraHost(status.serviceName);
413             break;
414         default:
415             MEDIA_ERR_LOG("HCameraHostManager::OnReceive unexpected service status %{public}d", status.status);
416     }
417 }
418 
AddCameraHost(const std::string & svcName)419 void HCameraHostManager::AddCameraHost(const std::string& svcName)
420 {
421     MEDIA_INFO_LOG("HCameraHostManager::AddCameraHost camera host %{public}s added", svcName.c_str());
422     std::lock_guard<std::mutex> lock(mutex_);
423     if (std::any_of(cameraHostInfos_.begin(), cameraHostInfos_.end(),
424                     [&svcName](const auto& camHost) { return camHost->GetName() == svcName; })) {
425         MEDIA_INFO_LOG("HCameraHostManager::AddCameraHost camera host  %{public}s already exists", svcName.c_str());
426         return;
427     }
428     sptr<HCameraHostManager::CameraHostInfo> cameraHost = new HCameraHostManager::CameraHostInfo(this, svcName);
429     if (!cameraHost->Init()) {
430         MEDIA_ERR_LOG("HCameraHostManager::AddCameraHost failed due to init failure");
431         return;
432     }
433     cameraHostInfos_.push_back(cameraHost);
434     std::vector<std::string> cameraIds;
435     if (statusCallback_ && cameraHost->GetCameras(cameraIds) == CAMERA_OK) {
436         for (const auto& cameraId : cameraIds) {
437             statusCallback_->OnCameraStatus(cameraId, CAMERA_STATUS_AVAILABLE);
438         }
439     }
440 }
441 
RemoveCameraHost(const std::string & svcName)442 void HCameraHostManager::RemoveCameraHost(const std::string& svcName)
443 {
444     MEDIA_INFO_LOG("HCameraHostManager::RemoveCameraHost camera host %{public}s removed", svcName.c_str());
445     std::lock_guard<std::mutex> lock(mutex_);
446     auto it = std::find_if(cameraHostInfos_.begin(), cameraHostInfos_.end(),
447                            [&svcName](const auto& camHost) { return camHost->GetName() == svcName; });
448     if (it == cameraHostInfos_.end()) {
449         MEDIA_WARNING_LOG("HCameraHostManager::RemoveCameraHost camera host %{public}s doesn't exist", svcName.c_str());
450         return;
451     }
452     std::vector<std::string> cameraIds;
453     if ((*it)->GetCameras(cameraIds) == CAMERA_OK) {
454         for (const auto& cameraId : cameraIds) {
455             (*it)->OnCameraStatus(cameraId, Camera::UN_AVAILABLE);
456         }
457     }
458     cameraHostInfos_.erase(it);
459 }
460 
FindCameraHostInfo(const std::string & cameraId)461 sptr<HCameraHostManager::CameraHostInfo> HCameraHostManager::FindCameraHostInfo(const std::string& cameraId)
462 {
463     std::lock_guard<std::mutex> lock(mutex_);
464     for (const auto& cameraHostInfo : cameraHostInfos_) {
465         if (cameraHostInfo->IsCameraSupported(cameraId)) {
466             return cameraHostInfo;
467         }
468     }
469     return nullptr;
470 }
471 } // namespace CameraStandard
472 } // namespace OHOS
473