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