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