1 /*
2 * Copyright (c) 2021 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 "camera_host_impl.h"
17 #include <algorithm>
18 #include "idevice_manager.h"
19 #include "camera_host_config.h"
20 #include "metadata_utils.h"
21
22 #include "v1_0/icamera_host_callback.h"
23 #include "v1_0/icamera_device.h"
24
25 namespace OHOS::Camera {
CameraHostImplGetInstance(void)26 extern "C" ICameraHost *CameraHostImplGetInstance(void)
27 {
28 using OHOS::Camera::CameraHostImpl;
29 CameraHostImpl *service = new (std::nothrow) CameraHostImpl();
30 if (service == nullptr) {
31 return nullptr;
32 }
33
34 service->Init();
35 return service;
36 }
37
CameraHostImpl()38 CameraHostImpl::CameraHostImpl()
39 {
40 CAMERA_LOGD("ctor, instance = %{public}p", this);
41 }
42
~CameraHostImpl()43 CameraHostImpl::~CameraHostImpl()
44 {
45 CAMERA_LOGD("dtor, instance = %{public}p", this);
46 }
47
Init()48 CamRetCode CameraHostImpl::Init()
49 {
50 std::shared_ptr<IDeviceManager> deviceManager =
51 IDeviceManager::GetInstance();
52 if (deviceManager == nullptr) {
53 return INVALID_ARGUMENT;
54 }
55
56 RetCode ret = RC_OK;
57 ret = deviceManager->Init();
58 if (ret == RC_ERROR) {
59 return INVALID_ARGUMENT;
60 }
61
62 CameraHostConfig *config = CameraHostConfig::GetInstance();
63 if (config == nullptr) {
64 return INVALID_ARGUMENT;
65 }
66
67 std::vector<std::string> cameraIds;
68 RetCode rc = config->GetCameraIds(cameraIds);
69 if (rc != RC_OK) {
70 CAMERA_LOGE("host get camera id failed.");
71 return INVALID_ARGUMENT;
72 }
73
74 for (auto &cameraId : cameraIds) {
75 std::vector<std::string> phyCameraIds;
76 rc = config->GetPhysicCameraIds(cameraId, phyCameraIds);
77 if (rc != RC_OK) {
78 continue;
79 }
80 std::shared_ptr<CameraDeviceImpl> cameraDevice =
81 CameraDeviceImpl::CreateCameraDevice(cameraId);
82 if (cameraDevice != nullptr) {
83 cameraDeviceMap_.insert(std::make_pair(cameraId, cameraDevice));
84 } else {
85 CAMERA_LOGW("host implement new device failed [cameraid = %{public}s].", cameraId.c_str());
86 }
87 }
88
89 deviceManager->SetHotplugDevCallBack([this](const std::shared_ptr<CameraAbility> &meta,
90 const bool &status, const CameraId &cameraId) {
91 CameraStatus cameraStatus = status ? AVAILABLE : UN_AVAILABLE;
92 OnCameraStatus(cameraId, cameraStatus, meta);
93 });
94 return HDI::Camera::V1_0::NO_ERROR;
95 }
96
SetCallback(const OHOS::sptr<ICameraHostCallback> & callbackObj)97 int32_t CameraHostImpl::SetCallback(const OHOS::sptr<ICameraHostCallback> &callbackObj)
98 {
99 DFX_LOCAL_HITRACE_BEGIN;
100
101 if (callbackObj == nullptr) {
102 CAMERA_LOGW("host callback is null.");
103 return INVALID_ARGUMENT;
104 }
105
106 cameraHostCallback_ = callbackObj;
107
108 DFX_LOCAL_HITRACE_END;
109 return HDI::Camera::V1_0::NO_ERROR;
110 }
111
GetCameraIds(std::vector<std::string> & cameraIds)112 int32_t CameraHostImpl::GetCameraIds(std::vector<std::string> &cameraIds)
113 {
114 DFX_LOCAL_HITRACE_BEGIN;
115
116 CameraHostConfig *config = CameraHostConfig::GetInstance();
117 if (config == nullptr) {
118 return INVALID_ARGUMENT;
119 }
120 RetCode rc = config->GetCameraIds(cameraIds);
121 if (rc != RC_OK) {
122 return INVALID_ARGUMENT;
123 }
124
125 DFX_LOCAL_HITRACE_END;
126 return HDI::Camera::V1_0::NO_ERROR;
127 }
128
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)129 int32_t CameraHostImpl::GetCameraAbility(const std::string &cameraId,
130 std::vector<uint8_t>& cameraAbility)
131 {
132 DFX_LOCAL_HITRACE_BEGIN;
133 CameraHostConfig *config = CameraHostConfig::GetInstance();
134 if (config == nullptr) {
135 return INVALID_ARGUMENT;
136 }
137 std::shared_ptr<CameraAbility> ability;
138 RetCode rc = config->GetCameraAbility(cameraId, ability);
139 if (rc != RC_OK) {
140 return INVALID_ARGUMENT;
141 }
142
143 MetadataUtils::ConvertMetadataToVec(ability, cameraAbility);
144 DFX_LOCAL_HITRACE_END;
145 return HDI::Camera::V1_0::NO_ERROR;
146 }
147
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)148 int32_t CameraHostImpl::OpenCamera(const std::string& cameraId, const sptr<ICameraDeviceCallback>& callbackObj,
149 sptr<ICameraDevice>& device)
150 {
151 CAMERA_LOGD("OpenCamera entry");
152 DFX_LOCAL_HITRACE_BEGIN;
153 if (CameraIdInvalid(cameraId) != RC_OK || callbackObj == nullptr) {
154 CAMERA_LOGW("open camera id is empty or callback is null.");
155 return INVALID_ARGUMENT;
156 }
157
158 auto itr = cameraDeviceMap_.find(cameraId);
159 if (itr == cameraDeviceMap_.end()) {
160 CAMERA_LOGE("camera device not found.");
161 return INSUFFICIENT_RESOURCES;
162 }
163 CAMERA_LOGD("OpenCamera cameraId find success.");
164
165 std::shared_ptr<CameraDeviceImpl> cameraDevice = itr->second;
166 if (cameraDevice == nullptr) {
167 CAMERA_LOGE("camera device is null.");
168 return INSUFFICIENT_RESOURCES;
169 }
170
171 CamRetCode ret = cameraDevice->SetCallback(callbackObj);
172 CHECK_IF_NOT_EQUAL_RETURN_VALUE(ret, HDI::Camera::V1_0::NO_ERROR, ret);
173
174 CameraHostConfig *config = CameraHostConfig::GetInstance();
175 CHECK_IF_PTR_NULL_RETURN_VALUE(config, INVALID_ARGUMENT);
176
177 std::vector<std::string> phyCameraIds;
178 RetCode rc = config->GetPhysicCameraIds(cameraId, phyCameraIds);
179 if (rc != RC_OK) {
180 CAMERA_LOGE("get physic cameraId failed.");
181 return DEVICE_ERROR;
182 }
183 if (CameraPowerUp(cameraId, phyCameraIds) != RC_OK) {
184 CAMERA_LOGE("camera powerup failed.");
185 CameraPowerDown(phyCameraIds);
186 return DEVICE_ERROR;
187 }
188
189 auto sptrDevice = deviceBackup_.find(cameraId);
190 if (sptrDevice == deviceBackup_.end()) {
191 #ifdef CAMERA_BUILT_ON_OHOS_LITE
192 deviceBackup_[cameraId] = cameraDevice;
193 #else
194 deviceBackup_[cameraId] = cameraDevice.get();
195 #endif
196 }
197 device = deviceBackup_[cameraId];
198 cameraDevice->SetStatus(true);
199 CAMERA_LOGD("open camera success.");
200 DFX_LOCAL_HITRACE_END;
201 return HDI::Camera::V1_0::NO_ERROR;
202 }
203
CameraIdInvalid(const std::string & cameraId)204 RetCode CameraHostImpl::CameraIdInvalid(const std::string &cameraId)
205 {
206 if (cameraId.empty()) {
207 return RC_ERROR;
208 }
209
210 CameraHostConfig *config = CameraHostConfig::GetInstance();
211 if (config == nullptr) {
212 return RC_ERROR;
213 }
214 std::vector<std::string> cameraIds;
215 RetCode ret = config->GetCameraIds(cameraIds);
216 if (ret != RC_OK || cameraIds.empty()) {
217 return RC_ERROR;
218 }
219
220 auto itr = std::find(cameraIds.begin(), cameraIds.end(), cameraId);
221 if (itr == cameraIds.end()) {
222 return RC_ERROR;
223 }
224
225 return RC_OK;
226 }
227
CameraPowerUp(const std::string & cameraId,const std::vector<std::string> & phyCameraIds)228 RetCode CameraHostImpl::CameraPowerUp(const std::string &cameraId,
229 const std::vector<std::string> &phyCameraIds)
230 {
231 FlashlightStatus flashlightStatus = FLASHLIGHT_UNAVAILABLE;
232 RetCode rc = SetFlashlight(phyCameraIds, false, flashlightStatus);
233 if (rc != RC_OK) {
234 CAMERA_LOGW("flash light close failed. [cameraId = %{public}s]", cameraId.c_str());
235 }
236 if (cameraHostCallback_ != nullptr) {
237 cameraHostCallback_->OnFlashlightStatus(cameraId, flashlightStatus);
238 }
239
240 std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
241 if (deviceManager == nullptr) {
242 CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
243 return RC_ERROR;
244 }
245
246 for (auto &phyCameraId : phyCameraIds) {
247 auto itr = CameraHostConfig::enumCameraIdMap_.find(phyCameraId);
248 if (itr == CameraHostConfig::enumCameraIdMap_.end()) {
249 CAMERA_LOGW("config phyCameraId undefined in device manager.");
250 continue;
251 }
252 rc = deviceManager->PowerUp(itr->second);
253 if (rc != RC_OK) {
254 CAMERA_LOGE("physic camera powerup failed [phyCameraId = %{public}s].", phyCameraId.c_str());
255 return RC_ERROR;
256 }
257 }
258 CAMERA_LOGD("camera powerup success.");
259
260 return RC_OK;
261 }
262
CameraPowerDown(const std::vector<std::string> & phyCameraIds)263 void CameraHostImpl::CameraPowerDown(const std::vector<std::string> &phyCameraIds)
264 {
265 std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
266 if (deviceManager == nullptr) {
267 CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
268 return;
269 }
270
271 RetCode ret = RC_OK;
272 for (auto &cameraId : phyCameraIds) {
273 auto itr = CameraHostConfig::enumCameraIdMap_.find(cameraId);
274 if (itr == CameraHostConfig::enumCameraIdMap_.end()) {
275 CAMERA_LOGW("config cameraId undefined in device manager.");
276 continue;
277 }
278
279 ret = deviceManager->PowerDown(itr->second);
280 if (ret != RC_OK) {
281 CAMERA_LOGE("physic camera powerdown failed [cameraId = %{public}s].", cameraId.c_str());
282 continue;
283 }
284 CAMERA_LOGD("[cameraId = %{public}s] powerdown success.", cameraId.c_str());
285 }
286 }
287
SetFlashlight(const std::string & cameraId,bool isEnable)288 int32_t CameraHostImpl::SetFlashlight(const std::string &cameraId, bool isEnable)
289 {
290 DFX_LOCAL_HITRACE_BEGIN;
291 if (CameraIdInvalid(cameraId) != RC_OK) {
292 CAMERA_LOGE("camera id is not found [cameraId = %{public}s].", cameraId.c_str());
293 return INVALID_ARGUMENT;
294 }
295
296 for (auto &itr : cameraDeviceMap_) {
297 std::shared_ptr<CameraDeviceImpl> cameraDevice = itr.second;
298 if (cameraDevice->IsOpened()) {
299 CAMERA_LOGE("camera id opend [cameraId = %{public}s].", itr.first.c_str());
300 return METHOD_NOT_SUPPORTED;
301 }
302 }
303
304 CameraHostConfig *config = CameraHostConfig::GetInstance();
305 if (config == nullptr) {
306 return INVALID_ARGUMENT;
307 }
308 std::vector<std::string> phyCameraIds;
309 RetCode rc = config->GetPhysicCameraIds(cameraId, phyCameraIds);
310 if (rc != RC_OK) {
311 CAMERA_LOGE("get physic cameraIds failed.");
312 return DEVICE_ERROR;
313 }
314
315 FlashlightStatus flashlightStatus = FLASHLIGHT_UNAVAILABLE;
316 rc = SetFlashlight(phyCameraIds, isEnable, flashlightStatus);
317 if (rc == RC_OK && flashlightStatus != FLASHLIGHT_UNAVAILABLE) {
318 if (cameraHostCallback_ != nullptr) {
319 cameraHostCallback_->OnFlashlightStatus(cameraId, flashlightStatus);
320 }
321 return HDI::Camera::V1_0::NO_ERROR;
322 } else {
323 return DEVICE_ERROR;
324 }
325 DFX_LOCAL_HITRACE_END;
326 }
327
SetFlashlight(const std::vector<std::string> & phyCameraIds,bool isEnable,FlashlightStatus & flashlightStatus)328 RetCode CameraHostImpl::SetFlashlight(const std::vector<std::string> &phyCameraIds,
329 bool isEnable, FlashlightStatus &flashlightStatus)
330 {
331 std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
332 (void)phyCameraIds;
333 if (deviceManager == nullptr) {
334 CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
335 return RC_ERROR;
336 }
337
338 RetCode rc = deviceManager->SetFlashlight(FLASH_TORCH, isEnable);
339 if (rc == RC_OK) {
340 if (isEnable) {
341 flashlightStatus = FLASHLIGHT_OFF;
342 } else {
343 flashlightStatus = FLASHLIGHT_ON;
344 }
345 }
346
347 return rc;
348 }
349
OnCameraStatus(CameraId cameraId,CameraStatus status,const std::shared_ptr<CameraAbility> ability)350 void CameraHostImpl::OnCameraStatus(CameraId cameraId,
351 CameraStatus status, const std::shared_ptr<CameraAbility> ability)
352 {
353 CameraHostConfig *config = CameraHostConfig::GetInstance();
354 if (config == nullptr) {
355 CAMERA_LOGE("config is nullptr");
356 return;
357 }
358 if (cameraId < 0 && cameraId > CAMERA_MAX) {
359 CAMERA_LOGE("dvice manager callback cameraId error.");
360 return;
361 }
362 std::vector<std::string> physicalCameraIds;
363 std::string physicalCameraId = config->ReturnPhysicalCameraIdToString(cameraId);
364 if (physicalCameraId.size() == 0) {
365 CAMERA_LOGE("config cameraId undefined in device manager.");
366 return;
367 }
368 physicalCameraIds.push_back(physicalCameraId);
369
370 if (status == AVAILABLE) {
371 std::string logicalCameraId = config->ReturnEnableLogicalCameraId();
372 RetCode rc = config->AddCameraId(logicalCameraId, physicalCameraIds, ability);
373 if (rc == RC_OK && logicalCameraId.size() > 0) {
374 CAMERA_LOGI("add physicalCameraIds %{public}d logicalCameraId %{public}s",
375 static_cast<int>(cameraId), logicalCameraId.c_str());
376 if (cameraHostCallback_ != nullptr) {
377 cameraHostCallback_->OnCameraStatus(logicalCameraId, status);
378 }
379 }
380 std::shared_ptr<CameraDeviceImpl> cameraDevice =
381 CameraDeviceImpl::CreateCameraDevice(logicalCameraId);
382 if (cameraDevice != nullptr) {
383 cameraDeviceMap_[logicalCameraId] = cameraDevice;
384 }
385 } else {
386 std::string logicalCameraId =
387 config->ReturnLogicalCameraIdToString(physicalCameraIds[0]);
388 if (logicalCameraId.size() > 0) {
389 CAMERA_LOGI("physicalCameraIds %{public}d logicalCameraId %{public}s",
390 static_cast<int>(cameraId), logicalCameraId.c_str());
391 if (cameraHostCallback_ != nullptr) {
392 cameraHostCallback_->OnCameraStatus(logicalCameraId, status);
393 }
394 }
395 }
396 }
397 } // end namespace OHOS::Camera
398