1 /*
2 * Copyright (c) 2021-2024 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 "dcamera_host.h"
17
18 #include <cstdlib>
19 #include "iservice_registry.h"
20 #include "iproxy_broker.h"
21 #include "iservmgr_hdi.h"
22
23 #include "anonymous_string.h"
24 #include "distributed_hardware_log.h"
25 #include "metadata_utils.h"
26 #include "dcamera.h"
27
28 namespace OHOS {
29 namespace DistributedHardware {
30 OHOS::sptr<DCameraHost> DCameraHost::instance_ = nullptr;
31 DCameraHost::AutoRelease DCameraHost::autoRelease_;
32
CameraHostImplGetInstance(void)33 extern "C" ICameraHost *CameraHostImplGetInstance(void)
34 {
35 return static_cast<ICameraHost *>(DCameraHost::GetInstance().GetRefPtr());
36 }
37
GetInstance()38 OHOS::sptr<DCameraHost> DCameraHost::GetInstance()
39 {
40 if (instance_ == nullptr) {
41 instance_ = sptr<DCameraHost>(new DCameraHost());
42 if (instance_ == nullptr) {
43 DHLOGE("Get distributed camera host instance failed.");
44 return nullptr;
45 }
46 }
47 return instance_;
48 }
49
SetCallback(const sptr<HDI::Camera::V1_0::ICameraHostCallback> & callbackObj)50 int32_t DCameraHost::SetCallback(const sptr<HDI::Camera::V1_0::ICameraHostCallback> &callbackObj)
51 {
52 if (callbackObj == nullptr) {
53 DHLOGE("DCameraHost::SetCallback, input camera host callback is null.");
54 return CamRetCode::INVALID_ARGUMENT;
55 }
56 dCameraHostCallback_ = callbackObj;
57 dCameraHostRecipient_ = sptr<DCameraHostRecipient>(new DCameraHostRecipient());
58 return CamRetCode::NO_ERROR;
59 }
60
SetCallback_V1_2(const sptr<HDI::Camera::V1_2::ICameraHostCallback> & callbackObj)61 int32_t DCameraHost::SetCallback_V1_2(const sptr<HDI::Camera::V1_2::ICameraHostCallback> &callbackObj)
62 {
63 if (callbackObj == nullptr) {
64 DHLOGE("DCameraHost::SetCallback_V1_2, input camera host callback is null.");
65 return CamRetCode::INVALID_ARGUMENT;
66 }
67 dCameraHostCallback_V1_2_ = callbackObj;
68 dCameraHostRecipient_ = sptr<DCameraHostRecipient>(new DCameraHostRecipient());
69 return CamRetCode::NO_ERROR;
70 }
71
GetCameraIds(std::vector<std::string> & cameraIds)72 int32_t DCameraHost::GetCameraIds(std::vector<std::string> &cameraIds)
73 {
74 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
75 auto iter = dCameraDeviceMap_.begin();
76 while (iter != dCameraDeviceMap_.end()) {
77 if (!(iter->first).empty()) {
78 cameraIds.push_back(iter->first);
79 }
80 iter++;
81 }
82 return CamRetCode::NO_ERROR;
83 }
84
GetCameraAbilityFromDev(const std::string & cameraId,std::shared_ptr<CameraAbility> & cameraAbility)85 int32_t DCameraHost::GetCameraAbilityFromDev(const std::string &cameraId, std::shared_ptr<CameraAbility> &cameraAbility)
86 {
87 OHOS::sptr<DCameraDevice> device = nullptr;
88 {
89 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
90 auto iter = dCameraDeviceMap_.find(cameraId);
91 if (iter == dCameraDeviceMap_.end() || iter->second == nullptr) {
92 DHLOGE("DCameraHost::Get Cameradevice failed");
93 return CamRetCode::INVALID_ARGUMENT;
94 } else {
95 device = iter->second;
96 }
97 }
98 if (device->GetDCameraAbility(cameraAbility) != CamRetCode::NO_ERROR) {
99 DHLOGE("DCameraHost::GetCameraAbility, GetDCameraAbility failed.");
100 return CamRetCode::INVALID_ARGUMENT;
101 }
102 return CamRetCode::NO_ERROR;
103 }
104
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)105 int32_t DCameraHost::GetCameraAbility(const std::string &cameraId, std::vector<uint8_t> &cameraAbility)
106 {
107 if (IsCameraIdInvalid(cameraId)) {
108 DHLOGE("DCameraHost::GetCameraAbility, input cameraId is invalid.");
109 return CamRetCode::INVALID_ARGUMENT;
110 }
111 DHLOGI("DCameraHost::GetCameraAbility for cameraId: %{public}s", GetAnonyString(cameraId).c_str());
112 std::shared_ptr<CameraAbility> ability;
113 int32_t ret = GetCameraAbilityFromDev(cameraId, ability);
114 if (ret != CamRetCode::NO_ERROR) {
115 DHLOGE("DCameraHost::GetCameraAbility, GetCameraAbilityFromDev failed.");
116 return CamRetCode::INVALID_ARGUMENT;
117 }
118 bool retBool = OHOS::Camera::MetadataUtils::ConvertMetadataToVec(ability, cameraAbility);
119 if (!retBool) {
120 DHLOGE("DCameraHost::GetCameraAbility, ConvertMetadataToVec failed.");
121 return CamRetCode::INVALID_ARGUMENT;
122 }
123 do {
124 camera_metadata_item_t item;
125 constexpr uint32_t WIDTH_OFFSET = 1;
126 constexpr uint32_t HEIGHT_OFFSET = 2;
127 constexpr uint32_t UNIT_LENGTH = 3;
128 ret = OHOS::Camera::FindCameraMetadataItem(ability->get(),
129 OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &item);
130 DHLOGI("FindCameraMetadataItem item=%{public}u, count=%{public}u, dataType=%{public}u", item.item,
131 item.count, item.data_type);
132 if (ret != CAM_META_SUCCESS) {
133 DHLOGE("Failed to find stream configuration in camera ability with return code %{public}d", ret);
134 break;
135 }
136 if (item.count % UNIT_LENGTH != 0) {
137 DHLOGE("Invalid stream configuration count: %{public}u", item.count);
138 break;
139 }
140 for (uint32_t index = 0; index < item.count; index += UNIT_LENGTH) {
141 int32_t format = item.data.i32[index];
142 int32_t width = item.data.i32[index + WIDTH_OFFSET];
143 int32_t height = item.data.i32[index + HEIGHT_OFFSET];
144 DHLOGD("format: %{public}d, width: %{public}d, height: %{public}d", format, width, height);
145 }
146 } while (0);
147 return CamRetCode::NO_ERROR;
148 }
149
150 template<typename Callback, typename Device>
OpenCameraImpl(const std::string & cameraId,const Callback & callbackObj,Device & device)151 int32_t DCameraHost::OpenCameraImpl(const std::string &cameraId, const Callback &callbackObj, Device &device)
152 {
153 if (IsCameraIdInvalid(cameraId) || callbackObj == nullptr) {
154 DHLOGE("OpenCameraImpl, open camera id is invalid or camera device callback is null.");
155 return CamRetCode::INVALID_ARGUMENT;
156 }
157
158 DHLOGI("OpenCameraImpl for cameraId: %{public}s", GetAnonyString(cameraId).c_str());
159
160 OHOS::sptr<DCameraDevice> dcameraDevice = nullptr;
161 {
162 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
163 auto iter = dCameraDeviceMap_.find(cameraId);
164 if (iter == dCameraDeviceMap_.end()) {
165 DHLOGE("OpenCameraImpl, dcamera device not found.");
166 return CamRetCode::INSUFFICIENT_RESOURCES;
167 }
168
169 dcameraDevice = iter->second;
170 if (dcameraDevice == nullptr) {
171 DHLOGE("OpenCameraImpl, dcamera device is null.");
172 return INSUFFICIENT_RESOURCES;
173 }
174 }
175
176 if (dcameraDevice->IsOpened()) {
177 DHLOGE("OpenCameraImpl, dcamera device %{public}s already opened.", GetAnonyString(cameraId).c_str());
178 return CamRetCode::CAMERA_BUSY;
179 }
180
181 CamRetCode ret = dcameraDevice->OpenDCamera(callbackObj);
182 if (ret != CamRetCode::NO_ERROR) {
183 DHLOGE("OpenCameraImpl, open camera failed.");
184 return ret;
185 }
186 device = dcameraDevice;
187
188 DHLOGI("OpenCameraImpl, open camera %{public}s success.", GetAnonyString(cameraId).c_str());
189 return CamRetCode::NO_ERROR;
190 }
191
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<HDI::Camera::V1_0::ICameraDevice> & device)192 int32_t DCameraHost::OpenCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
193 sptr<HDI::Camera::V1_0::ICameraDevice> &device)
194 {
195 return OpenCameraImpl(cameraId, callbackObj, device);
196 }
197
OpenCamera_V1_1(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<HDI::Camera::V1_1::ICameraDevice> & device)198 int32_t DCameraHost::OpenCamera_V1_1(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
199 sptr<HDI::Camera::V1_1::ICameraDevice> &device)
200 {
201 return OpenCameraImpl(cameraId, callbackObj, device);
202 }
203
OpenCamera_V1_2(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<HDI::Camera::V1_2::ICameraDevice> & device)204 int32_t DCameraHost::OpenCamera_V1_2(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
205 sptr<HDI::Camera::V1_2::ICameraDevice> &device)
206 {
207 return OpenCameraImpl(cameraId, callbackObj, device);
208 }
209
OpenCamera_V1_3(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)210 int32_t DCameraHost::OpenCamera_V1_3(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
211 sptr<ICameraDevice> &device)
212 {
213 return OpenCameraImpl(cameraId, callbackObj, device);
214 }
215
OpenSecureCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)216 int32_t DCameraHost::OpenSecureCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
217 sptr<ICameraDevice> &device)
218 {
219 return OpenCameraImpl(cameraId, callbackObj, device);
220 }
221
GetResourceCost(const std::string & cameraId,OHOS::HDI::Camera::V1_3::CameraDeviceResourceCost & resourceCost)222 int32_t DCameraHost::GetResourceCost(const std::string &cameraId,
223 OHOS::HDI::Camera::V1_3::CameraDeviceResourceCost &resourceCost)
224 {
225 (void)cameraId;
226 (void)resourceCost;
227 return CamRetCode::METHOD_NOT_SUPPORTED;
228 }
229
NotifyDeviceStateChangeInfo(int notifyType,int deviceState)230 int32_t DCameraHost::NotifyDeviceStateChangeInfo(int notifyType, int deviceState)
231 {
232 (void)notifyType;
233 (void)deviceState;
234 DHLOGI("DCameraHost::NotifyDeviceStateChangeInfo, distributed camera not support.");
235
236 return CamRetCode::METHOD_NOT_SUPPORTED;
237 }
238
SetFlashlight(const std::string & cameraId,bool isEnable)239 int32_t DCameraHost::SetFlashlight(const std::string &cameraId, bool isEnable)
240 {
241 (void)cameraId;
242 (void)isEnable;
243 DHLOGI("DCameraHost::SetFlashlight, distributed camera not support.");
244
245 return CamRetCode::METHOD_NOT_SUPPORTED;
246 }
247
SetFlashlight_V1_2(float level)248 int32_t DCameraHost::SetFlashlight_V1_2(float level)
249 {
250 (void)level;
251 DHLOGI("DCameraHost::SetFlashlight_V1_2, distributed camera not support.");
252
253 return CamRetCode::METHOD_NOT_SUPPORTED;
254 }
255
PreCameraSwitch(const std::string & cameraId)256 int32_t DCameraHost::PreCameraSwitch(const std::string &cameraId)
257 {
258 (void)cameraId;
259 DHLOGI("DCameraHost::PreCameraSwitch, distributed camera not support.");
260
261 return CamRetCode::METHOD_NOT_SUPPORTED;
262 }
263
PrelaunchWithOpMode(const PrelaunchConfig & config,int32_t operationMode)264 int32_t DCameraHost::PrelaunchWithOpMode(const PrelaunchConfig &config, int32_t operationMode)
265 {
266 (void)config;
267 (void)operationMode;
268 DHLOGI("DCameraHost::PrelaunchWithOpMode, distributed camera not support.");
269
270 return CamRetCode::METHOD_NOT_SUPPORTED;
271 }
272
Prelaunch(const PrelaunchConfig & config)273 int32_t DCameraHost::Prelaunch(const PrelaunchConfig &config)
274 {
275 (void)config;
276 DHLOGI("DCameraHost::Prelaunch, distributed camera not support.");
277
278 return CamRetCode::METHOD_NOT_SUPPORTED;
279 }
280
AddDeviceParamCheck(const DHBase & dhBase,const std::string & sinkAbilityInfo,const std::string & sourceCodecInfo,const sptr<IDCameraProviderCallback> & callback)281 DCamRetCode DCameraHost::AddDeviceParamCheck(const DHBase &dhBase, const std::string& sinkAbilityInfo,
282 const std::string &sourceCodecInfo, const sptr<IDCameraProviderCallback> &callback)
283 {
284 if (IsDhBaseInfoInvalid(dhBase)) {
285 DHLOGE("DCameraHost::AddDCameraDevice, devId or dhId is invalid.");
286 return DCamRetCode::INVALID_ARGUMENT;
287 }
288 DHLOGI("DCameraHost::AddDCameraDevice for {devId: %{public}s, dhId: %{public}s}",
289 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
290
291 if (sinkAbilityInfo.empty() || sinkAbilityInfo.length() > ABILITYINFO_MAX_LENGTH) {
292 DHLOGE("DCameraHost::AddDCameraDevice, input sinkAbilityInfo is invalid.");
293 return DCamRetCode::INVALID_ARGUMENT;
294 }
295
296 if (sourceCodecInfo.empty() || sourceCodecInfo.length() > ABILITYINFO_MAX_LENGTH) {
297 DHLOGE("DCameraHost::AddDCameraDevice, input sourceCodecInfo is invalid.");
298 return DCamRetCode::INVALID_ARGUMENT;
299 }
300 if (GetCamDevNum() > MAX_DCAMERAS_NUMBER) {
301 DHLOGE("DCameraHost::AddDCameraDevice, cameras exceed the upper limit.");
302 return DCamRetCode::INVALID_ARGUMENT;
303 }
304 return DCamRetCode::SUCCESS;
305 }
306
AddDCameraDevice(const DHBase & dhBase,const std::string & sinkAbilityInfo,const std::string & sourceCodecInfo,const sptr<IDCameraProviderCallback> & callback)307 DCamRetCode DCameraHost::AddDCameraDevice(const DHBase &dhBase, const std::string& sinkAbilityInfo,
308 const std::string &sourceCodecInfo, const sptr<IDCameraProviderCallback> &callback)
309 {
310 if (AddDeviceParamCheck(dhBase, sinkAbilityInfo, sourceCodecInfo, callback) != DCamRetCode::SUCCESS) {
311 DHLOGE("DCameraHost::AddDCameraDevice, input param is invalid.");
312 return DCamRetCode::INVALID_ARGUMENT;
313 }
314 std::string dCameraId = dhBase.deviceId_ + "__" + dhBase.dhId_;
315 {
316 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
317 if (dCameraDeviceMap_.find(dCameraId) != dCameraDeviceMap_.end()) {
318 if (dCameraDeviceMap_[dCameraId] == nullptr) {
319 DHLOGI("AddDCameraDevice device is null");
320 return DCamRetCode::INVALID_ARGUMENT;
321 }
322 dCameraDeviceMap_[dCameraId]->SetDcameraAbility(sinkAbilityInfo);
323 DHLOGI("AddDCameraDevice refresh data success");
324 return DCamRetCode::SUCCESS;
325 }
326 }
327 OHOS::sptr<DCameraDevice> dcameraDevice(new (std::nothrow) DCameraDevice(dhBase, sinkAbilityInfo,
328 sourceCodecInfo));
329 if (dcameraDevice == nullptr) {
330 DHLOGE("DCameraHost::AddDCameraDevice, create dcamera device failed.");
331 return DCamRetCode::INVALID_ARGUMENT;
332 }
333 {
334 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
335 dCameraDeviceMap_[dCameraId] = dcameraDevice;
336 }
337 if (callback == nullptr) {
338 DHLOGE("DCameraHost::SetProviderCallback failed, callback is null");
339 return DCamRetCode::INVALID_ARGUMENT;
340 }
341 dcameraDevice->SetProviderCallback(callback);
342 if (dCameraHostCallback_ != nullptr) {
343 dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_ADD);
344 }
345 if (dCameraHostCallback_V1_2_ != nullptr) {
346 dCameraHostCallback_V1_2_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_ADD);
347 }
348 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<IDCameraProviderCallback>(callback);
349 if (remote != nullptr) {
350 remote->AddDeathRecipient(dCameraHostRecipient_);
351 }
352 DHLOGI("AddDCameraDevice create dcamera device success, dCameraId: %{public}s", GetAnonyString(dCameraId).c_str());
353 return DCamRetCode::SUCCESS;
354 }
355
GetCamDevNum()356 size_t DCameraHost::GetCamDevNum()
357 {
358 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
359 return dCameraDeviceMap_.size();
360 }
361
RemoveDCameraDevice(const DHBase & dhBase)362 DCamRetCode DCameraHost::RemoveDCameraDevice(const DHBase &dhBase)
363 {
364 DHLOGI("DCameraHost::RemoveDCameraDevice for {devId: %{public}s, dhId: %{public}s}",
365 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
366
367 std::string dCameraId = GetCameraIdByDHBase(dhBase);
368 if (dCameraId.empty()) {
369 DHLOGE("DCameraHost::RemoveDCameraDevice, dhBase not exist.");
370 return DCamRetCode::INVALID_ARGUMENT;
371 }
372
373 OHOS::sptr<DCameraDevice> dcameraDevice = GetDCameraDeviceByDHBase(dhBase);
374 if (dcameraDevice != nullptr) {
375 if (dcameraDevice->IsOpened()) {
376 dcameraDevice->Close();
377 }
378 dcameraDevice->SetProviderCallback(nullptr);
379 sptr<IDCameraProviderCallback> callback = dcameraDevice->GetProviderCallback();
380 if (callback != nullptr) {
381 sptr<IRemoteObject> remoteObj = OHOS::HDI::hdi_objcast<IDCameraProviderCallback>(callback);
382 if (remoteObj != nullptr) {
383 remoteObj->RemoveDeathRecipient(dCameraHostRecipient_);
384 }
385 }
386 }
387 {
388 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
389 dCameraDeviceMap_.erase(dCameraId);
390 }
391
392 if (dCameraHostCallback_ != nullptr) {
393 dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_RMV);
394 }
395
396 if (dCameraHostCallback_V1_2_ != nullptr) {
397 dCameraHostCallback_V1_2_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_RMV);
398 }
399
400 DHLOGI("DCameraHost::RemoveDCameraDevice, remove dcamera device success, dCameraId: %{public}s",
401 GetAnonyString(dCameraId).c_str());
402 return DCamRetCode::SUCCESS;
403 }
404
IsCameraIdInvalid(const std::string & cameraId)405 bool DCameraHost::IsCameraIdInvalid(const std::string &cameraId)
406 {
407 if (cameraId.empty() || cameraId.length() > ID_MAX_SIZE) {
408 return true;
409 }
410
411 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
412 auto iter = dCameraDeviceMap_.begin();
413 while (iter != dCameraDeviceMap_.end()) {
414 if (cameraId == iter->first) {
415 return false;
416 }
417 iter++;
418 }
419 return true;
420 }
421
GetCameraIdByDHBase(const DHBase & dhBase)422 std::string DCameraHost::GetCameraIdByDHBase(const DHBase &dhBase)
423 {
424 std::string dcameraId = dhBase.deviceId_ + "__" + dhBase.dhId_;
425 return dcameraId;
426 }
427
GetDCameraDeviceByDHBase(const DHBase & dhBase)428 OHOS::sptr<DCameraDevice> DCameraHost::GetDCameraDeviceByDHBase(const DHBase &dhBase)
429 {
430 std::string dCameraId = GetCameraIdByDHBase(dhBase);
431 if (dCameraId.empty()) {
432 DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dhBase not exist.");
433 return nullptr;
434 }
435
436 std::lock_guard<std::mutex> autoLock(deviceMapLock_);
437 auto iter = dCameraDeviceMap_.find(dCameraId);
438 if (iter == dCameraDeviceMap_.end()) {
439 DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dcamera device not found.");
440 return nullptr;
441 }
442 return iter->second;
443 }
444
NotifyDCameraStatus(const DHBase & dhBase,int32_t result)445 void DCameraHost::NotifyDCameraStatus(const DHBase &dhBase, int32_t result)
446 {
447 std::string dCameraId = GetCameraIdByDHBase(dhBase);
448 if (dCameraId.empty()) {
449 DHLOGE("DCameraHost::NotifyDCameraStatus, dhBase not exist.");
450 return;
451 }
452 if (dCameraHostCallback_ != nullptr) {
453 dCameraHostCallback_->OnCameraStatus(dCameraId, CameraStatus::UN_AVAILABLE);
454 }
455 if (dCameraHostCallback_V1_2_ != nullptr) {
456 dCameraHostCallback_V1_2_->OnCameraStatus(dCameraId, CameraStatus::UN_AVAILABLE);
457 }
458 }
459
OnRemoteDied(const wptr<IRemoteObject> & remote)460 void DCameraHost::DCameraHostRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
461 {
462 DHLOGE("Exit the current process.");
463 _Exit(0);
464 }
465 } // namespace DistributedHardware
466 } // namespace OHOS
467