• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_device.h"
17 
18 #include "anonymous_string.h"
19 #include "constants.h"
20 #include "dcamera.h"
21 #include "dcamera_host.h"
22 #include "dcamera_provider.h"
23 #include "distributed_hardware_log.h"
24 #include "metadata_utils.h"
25 
26 namespace OHOS {
27 namespace DistributedHardware {
28 using ErrorCallback = std::function<void (ErrorType, int32_t)>;
29 using ResultCallback = std::function<void (uint64_t, std::shared_ptr<OHOS::Camera::CameraMetadata>)>;
DCameraDevice(const DHBase & dhBase,const std::string & sinkAbilityInfo,const std::string & sourceAbilityInfo)30 DCameraDevice::DCameraDevice(const DHBase &dhBase, const std::string &sinkAbilityInfo,
31     const std::string &sourceAbilityInfo)
32     : isOpened_(false),
33       dCameraId_(GenerateCameraId(dhBase)),
34       dhBase_(dhBase),
35       dCameraAbilityInfo_(sinkAbilityInfo),
36       sourceAbilityInfo_(sourceAbilityInfo),
37       dCameraDeviceCallback_(nullptr),
38       dCameraStreamOperator_(nullptr),
39       dMetadataProcessor_(nullptr)
40 {
41     DHLOGI("DCameraDevice construct");
42     Init(sinkAbilityInfo, sourceAbilityInfo);
43 }
44 
Init(const std::string & sinkAbilityInfo,const std::string & sourceAbilityInfo)45 void DCameraDevice::Init(const std::string &sinkAbilityInfo, const std::string &sourceAbilityInfo)
46 {
47     if (dMetadataProcessor_ == nullptr) {
48         dMetadataProcessor_ = std::make_shared<DMetadataProcessor>();
49     }
50     dMetadataProcessor_->InitDCameraAbility(sinkAbilityInfo, sourceAbilityInfo);
51 }
52 
CreateDStreamOperator()53 DCamRetCode DCameraDevice::CreateDStreamOperator()
54 {
55     if (dCameraStreamOperator_ == nullptr) {
56         dCameraStreamOperator_ = new (std::nothrow) DStreamOperator(dMetadataProcessor_);
57         if (dCameraStreamOperator_ == nullptr) {
58             DHLOGE("Create distributed camera stream operator failed.");
59             return DEVICE_NOT_INIT;
60         }
61     }
62 
63     DCamRetCode ret = dCameraStreamOperator_->InitOutputConfigurations(dhBase_, dCameraAbilityInfo_,
64         sourceAbilityInfo_);
65     if (ret != SUCCESS) {
66         DHLOGE("Init distributed camera stream operator failed, ret=%d.", ret);
67         return ret;
68     }
69 
70     ErrorCallback onErrorCallback =
71         [this](ErrorType type, int32_t errorMsg) -> void {
72             if (dCameraDeviceCallback_) {
73                 DHLOGI("DCameraDevice onErrorCallback type: %u, errorMsg: %d", type, errorMsg);
74                 dCameraDeviceCallback_->OnError(type, errorMsg);
75             }
76         };
77     ResultCallback onResultCallback =
78         [this](uint64_t timestamp, const std::shared_ptr<OHOS::Camera::CameraMetadata> &result) -> void {
79             if (dCameraDeviceCallback_) {
80                 DHLOGI("DCameraDevice onResultCallback timestamp: %llu", timestamp);
81                 std::vector<uint8_t> metadata;
82                 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(result, metadata);
83                 dCameraDeviceCallback_->OnResult(timestamp, metadata);
84             }
85         };
86     dCameraStreamOperator_->SetDeviceCallback(onErrorCallback, onResultCallback);
87 
88     return ret;
89 }
90 
GetStreamOperator(const sptr<IStreamOperatorCallback> & callbackObj,sptr<IStreamOperator> & streamOperator)91 int32_t DCameraDevice::GetStreamOperator(const sptr<IStreamOperatorCallback> &callbackObj,
92     sptr<IStreamOperator> &streamOperator)
93 {
94     if (callbackObj == nullptr) {
95         DHLOGE("DCameraDevice::GetStreamOperator, input stream operator callback is null.");
96         return CamRetCode::INVALID_ARGUMENT;
97     }
98 
99     if (dCameraStreamOperator_ == nullptr) {
100         DHLOGE("DCameraDevice::GetStreamOperator, input distributed camera stream operator is null.");
101         return CamRetCode::DEVICE_ERROR;
102     }
103 
104     DCamRetCode ret = dCameraStreamOperator_->SetCallBack(callbackObj);
105     if (ret != SUCCESS) {
106         DHLOGE("Set stream operator callbackObj failed, ret=%d.", ret);
107         return MapToExternalRetCode(ret);
108     }
109 
110     streamOperator = dCameraStreamOperator_;
111     return CamRetCode::NO_ERROR;
112 }
113 
UpdateSettings(const std::vector<uint8_t> & settings)114 int32_t DCameraDevice::UpdateSettings(const std::vector<uint8_t>& settings)
115 {
116     if (settings.empty() || settings.size() > METADATA_CAPACITY_MAX_SIZE) {
117         DHLOGE("DCameraDevice::UpdateSettings, input settings is invalid.");
118         return CamRetCode::INVALID_ARGUMENT;
119     }
120 
121     if (!IsOpened()) {
122         DHLOGE("DCameraDevice::UpdateSettings, dcamera device %s already closed.", GetAnonyString(dCameraId_).c_str());
123         return CamRetCode::CAMERA_CLOSED;
124     }
125 
126     std::shared_ptr<OHOS::Camera::CameraMetadata> updateSettings = nullptr;
127     OHOS::Camera::MetadataUtils::ConvertVecToMetadata(settings, updateSettings);
128     std::string abilityString = OHOS::Camera::MetadataUtils::EncodeToString(updateSettings);
129     std::string encodeString = Base64Encode(reinterpret_cast<const unsigned char *>(abilityString.c_str()),
130         abilityString.length());
131 
132     DCameraSettings dcSetting;
133     dcSetting.type_ = DCSettingsType::UPDATE_METADATA;
134     dcSetting.value_ = encodeString;
135 
136     std::vector<DCameraSettings> dcSettings;
137     dcSettings.push_back(dcSetting);
138 
139     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
140     if (provider == nullptr) {
141         DHLOGE("Distributed camera provider instance is null.");
142         return CamRetCode::DEVICE_ERROR;
143     }
144     int32_t ret = provider->UpdateSettings(dhBase_, dcSettings);
145 
146     return MapToExternalRetCode(static_cast<DCamRetCode>(ret));
147 }
148 
GetSettings(std::vector<uint8_t> & settings)149 int32_t DCameraDevice::GetSettings(std::vector<uint8_t> &settings)
150 {
151     if (settings.empty()) {
152         DHLOGE("Get settings failed.");
153         return CamRetCode::DEVICE_ERROR;
154     }
155     return CamRetCode::NO_ERROR;
156 }
157 
SetResultMode(ResultCallbackMode mode)158 int32_t DCameraDevice::SetResultMode(ResultCallbackMode mode)
159 {
160     if (dMetadataProcessor_ == nullptr) {
161         DHLOGE("Metadata processor not init.");
162         return CamRetCode::DEVICE_ERROR;
163     }
164 
165     DCamRetCode ret = dMetadataProcessor_->SetMetadataResultMode(mode);
166     if (ret != SUCCESS) {
167         DHLOGE("Set metadata result mode failed, ret=%d.", ret);
168     }
169     return MapToExternalRetCode(ret);
170 }
171 
GetEnabledResults(std::vector<int32_t> & results)172 int32_t DCameraDevice::GetEnabledResults(std::vector<int32_t> &results)
173 {
174     if (dMetadataProcessor_ == nullptr) {
175         DHLOGE("Metadata processor not init.");
176         return CamRetCode::DEVICE_ERROR;
177     }
178 
179     DCamRetCode ret = dMetadataProcessor_->GetEnabledMetadataResults(results);
180     if (ret != SUCCESS) {
181         DHLOGE("Get enabled metadata results failed, ret=%d.", ret);
182     }
183     return MapToExternalRetCode(ret);
184 }
185 
EnableResult(const std::vector<int32_t> & results)186 int32_t DCameraDevice::EnableResult(const std::vector<int32_t> &results)
187 {
188     if (results.empty() || results.size() > METADATA_CAPACITY_MAX_SIZE) {
189         DHLOGE("DCameraDevice::EnableResult, input results is invalid.");
190         return CamRetCode::DEVICE_ERROR;
191     }
192 
193     if (dMetadataProcessor_ == nullptr) {
194         DHLOGE("Metadata processor not init.");
195         return CamRetCode::DEVICE_ERROR;
196     }
197 
198     DCamRetCode ret = dMetadataProcessor_->EnableMetadataResult(results);
199     if (ret != SUCCESS) {
200         DHLOGE("Enable metadata result failed, ret=%d.", ret);
201         return MapToExternalRetCode(ret);
202     }
203 
204     stringstream sstream;
205     std::reverse_copy(results.begin(), results.end(), ostream_iterator<int32_t>(sstream, ""));
206     DCameraSettings dcSetting;
207     dcSetting.type_ = DCSettingsType::ENABLE_METADATA;
208     dcSetting.value_ = sstream.str();
209 
210     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
211     if (provider == nullptr) {
212         DHLOGE("Enable metadata failed, provider is nullptr.");
213         return CamRetCode::DEVICE_ERROR;
214     }
215     std::vector<DCameraSettings> dcSettings;
216     dcSettings.push_back(dcSetting);
217     int32_t retProv = provider->UpdateSettings(dhBase_, dcSettings);
218     return MapToExternalRetCode(static_cast<DCamRetCode>(retProv));
219 }
220 
DisableResult(const std::vector<int32_t> & results)221 int32_t DCameraDevice::DisableResult(const std::vector<int32_t> &results)
222 {
223     if (results.empty() || results.size() > METADATA_CAPACITY_MAX_SIZE) {
224         DHLOGE("DCameraDevice::DisableResult, input results is invalid.");
225         return CamRetCode::DEVICE_ERROR;
226     }
227 
228     if (dMetadataProcessor_ == nullptr) {
229         DHLOGE("Metadata processor not init.");
230         return CamRetCode::DEVICE_ERROR;
231     }
232 
233     DCamRetCode ret = dMetadataProcessor_->DisableMetadataResult(results);
234     if (ret != SUCCESS) {
235         DHLOGE("Disable metadata result failed, ret=%d.", ret);
236         return MapToExternalRetCode(ret);
237     }
238 
239     stringstream sstream;
240     std::reverse_copy(results.begin(), results.end(), ostream_iterator<int32_t>(sstream, ""));
241     DCameraSettings dcSetting;
242     dcSetting.type_ = DCSettingsType::DISABLE_METADATA;
243     dcSetting.value_ = sstream.str();
244 
245     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
246     if (provider == nullptr) {
247         DHLOGE("Metadata processor provider is nullptr.");
248         return CamRetCode::DEVICE_ERROR;
249     }
250     std::vector<DCameraSettings> dcSettings;
251     dcSettings.push_back(dcSetting);
252     int32_t retProv = provider->UpdateSettings(dhBase_, dcSettings);
253     return MapToExternalRetCode(static_cast<DCamRetCode>(retProv));
254 }
255 
Close()256 int32_t DCameraDevice::Close()
257 {
258     DHLOGI("DCameraDevice::Close distributed camera: %s", GetAnonyString(dCameraId_).c_str());
259 
260     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
261     if ((provider != nullptr) && (dCameraStreamOperator_ != nullptr)) {
262         std::vector<int> streamIds = dCameraStreamOperator_->GetStreamIds();
263         provider->StopCapture(dhBase_, streamIds);
264     }
265     if (dCameraStreamOperator_ != nullptr) {
266         dCameraStreamOperator_->Release();
267         dCameraStreamOperator_ = nullptr;
268     }
269     if (provider != nullptr) {
270         provider->CloseSession(dhBase_);
271     }
272     if (dMetadataProcessor_ != nullptr) {
273         dMetadataProcessor_->ResetEnableResults();
274     }
275     dCameraDeviceCallback_ = nullptr;
276     isOpenSessFailed_ = false;
277     isOpened_ = false;
278     return CamRetCode::NO_ERROR;
279 }
280 
OpenDCamera(const OHOS::sptr<ICameraDeviceCallback> & callback)281 CamRetCode DCameraDevice::OpenDCamera(const OHOS::sptr<ICameraDeviceCallback> &callback)
282 {
283     if (callback == nullptr) {
284         DHLOGE("Input callback is null.");
285         return CamRetCode::INVALID_ARGUMENT;
286     }
287     dCameraDeviceCallback_ = callback;
288 
289     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
290     if (provider == nullptr) {
291         DHLOGE("Get distributed camera provider instance is null.");
292         return CamRetCode::DEVICE_ERROR;
293     }
294     int32_t ret = provider->OpenSession(dhBase_);
295     if (ret != DCamRetCode::SUCCESS) {
296         DHLOGE("Open distributed camera control session failed, ret = %d.", ret);
297         return MapToExternalRetCode(static_cast<DCamRetCode>(ret));
298     }
299 
300     unique_lock<mutex> lock(openSesslock_);
301     auto st = openSessCV_.wait_for(lock, chrono::seconds(WAIT_OPEN_TIMEOUT_SEC));
302     if (st == cv_status::timeout) {
303         DHLOGE("Wait for distributed camera session open timeout.");
304         return CamRetCode::DEVICE_ERROR;
305     }
306     {
307         unique_lock<mutex> openStateLock(isOpenSessFailedlock_);
308         if (isOpenSessFailed_) {
309             DHLOGE("Open distributed camera session failed.");
310             return CamRetCode::DEVICE_ERROR;
311         }
312     }
313 
314     DCamRetCode retDCode = CreateDStreamOperator();
315     if (ret != SUCCESS) {
316         DHLOGE("Create distributed camera stream operator failed.");
317         return MapToExternalRetCode(retDCode);
318     }
319     isOpened_ = true;
320 
321     return MapToExternalRetCode(retDCode);
322 }
323 
GetDCameraAbility(std::shared_ptr<CameraAbility> & ability)324 CamRetCode DCameraDevice::GetDCameraAbility(std::shared_ptr<CameraAbility> &ability)
325 {
326     if (dMetadataProcessor_ == nullptr) {
327         DHLOGE("Metadata processor not init.");
328         return CamRetCode::DEVICE_ERROR;
329     }
330 
331     DCamRetCode ret = dMetadataProcessor_->GetDCameraAbility(ability);
332     if (ret != SUCCESS) {
333         DHLOGE("Get distributed camera ability failed, ret=%d.", ret);
334     }
335     return MapToExternalRetCode(ret);
336 }
337 
AcquireBuffer(int streamId,DCameraBuffer & buffer)338 DCamRetCode DCameraDevice::AcquireBuffer(int streamId, DCameraBuffer &buffer)
339 {
340     if (dCameraStreamOperator_ == nullptr) {
341         DHLOGE("Stream operator not init.");
342         return DEVICE_NOT_INIT;
343     }
344 
345     DCamRetCode ret = dCameraStreamOperator_->AcquireBuffer(streamId, buffer);
346     if (ret != SUCCESS) {
347         DHLOGE("Acquire buffer failed, ret=%d.", ret);
348     }
349     return ret;
350 }
351 
ShutterBuffer(int streamId,const DCameraBuffer & buffer)352 DCamRetCode DCameraDevice::ShutterBuffer(int streamId, const DCameraBuffer &buffer)
353 {
354     if (dCameraStreamOperator_ == nullptr) {
355         DHLOGE("Stream operator not init.");
356         return DEVICE_NOT_INIT;
357     }
358 
359     DCamRetCode ret = dCameraStreamOperator_->ShutterBuffer(streamId, buffer);
360     if (ret != SUCCESS) {
361         DHLOGE("Shutter buffer failed, ret=%d.", ret);
362     }
363     return ret;
364 }
365 
OnSettingsResult(const std::shared_ptr<DCameraSettings> & result)366 DCamRetCode DCameraDevice::OnSettingsResult(const std::shared_ptr<DCameraSettings> &result)
367 {
368     if (result == nullptr) {
369         DHLOGE("Input camera settings is null.");
370         return DCamRetCode::INVALID_ARGUMENT;
371     }
372 
373     if (dMetadataProcessor_ == nullptr) {
374         DHLOGE("Metadata processor not init.");
375         return DCamRetCode::DEVICE_NOT_INIT;
376     }
377 
378     if (result->type_ != DCSettingsType::METADATA_RESULT) {
379         DHLOGE("Invalid camera setting type = %d.", result->type_);
380         return DCamRetCode::INVALID_ARGUMENT;
381     }
382     if ((result->value_).empty()) {
383         DHLOGE("Camera settings result is empty.");
384         return DCamRetCode::INVALID_ARGUMENT;
385     }
386 
387     DCamRetCode ret = dMetadataProcessor_->SaveResultMetadata(result->value_);
388     if (ret != DCamRetCode::SUCCESS) {
389         DHLOGE("Save result metadata failed, ret = %d", ret);
390     }
391     return ret;
392 }
393 
Notify(const std::shared_ptr<DCameraHDFEvent> & event)394 DCamRetCode DCameraDevice::Notify(const std::shared_ptr<DCameraHDFEvent> &event)
395 {
396     DHLOGI("DCameraDevice::Notify for event type = %d, result = %d, content = %s.", event->type_, event->result_,
397         event->content_.c_str());
398     if ((event->type_ != DCameraEventType::DCAMERA_MESSAGE) && (event->type_ != DCameraEventType::DCAMERA_OPERATION)) {
399         DHLOGE("Invalid distributed camera event type = %d.", event->type_);
400         return DCamRetCode::INVALID_ARGUMENT;
401     }
402     switch (event->result_) {
403         case DCameraEventResult::DCAMERA_EVENT_CHANNEL_CONNECTED: {
404             IsOpenSessFailedState(false);
405             break;
406         }
407         case DCameraEventResult::DCAMERA_EVENT_OPEN_CHANNEL_ERROR: {
408             IsOpenSessFailedState(true);
409             break;
410         }
411         case DCameraEventResult::DCAMERA_EVENT_CHANNEL_DISCONNECTED: {
412             NotifyCameraError(ErrorType::DEVICE_DISCONNECT);
413             break;
414         }
415         case DCameraEventResult::DCAMERA_EVENT_CONFIG_STREAMS_ERROR:
416         case DCameraEventResult::DCAMERA_EVENT_START_CAPTURE_ERROR: {
417             NotifyStartCaptureError();
418             break;
419         }
420         case DCameraEventResult::DCAMERA_EVENT_DEVICE_ERROR: {
421             NotifyCameraError(ErrorType::DRIVER_ERROR);
422             break;
423         }
424         case DCameraEventResult::DCAMERA_EVENT_DEVICE_PREEMPT: {
425             NotifyCameraError(ErrorType::DEVICE_PREEMPT);
426             break;
427         }
428         case DCameraEventResult::DCAMERA_EVENT_DEVICE_IN_USE: {
429             NotifyCameraError(ErrorType::DCAMERA_ERROR_DEVICE_IN_USE);
430             break;
431         }
432         case DCameraEventResult::DCAMERA_EVENT_NO_PERMISSION: {
433             NotifyCameraError(ErrorType::DCAMERA_ERROR_NO_PERMISSION);
434             break;
435         }
436         default:
437             break;
438     }
439     return SUCCESS;
440 }
441 
IsOpenSessFailedState(bool state)442 void DCameraDevice::IsOpenSessFailedState(bool state)
443 {
444     {
445         unique_lock<mutex> lock(isOpenSessFailedlock_);
446         isOpenSessFailed_ = state;
447     }
448     openSessCV_.notify_one();
449 }
450 
NotifyStartCaptureError()451 void DCameraDevice::NotifyStartCaptureError()
452 {
453     if (dCameraDeviceCallback_ != nullptr) {
454         dCameraDeviceCallback_->OnError(ErrorType::REQUEST_TIMEOUT, 0);
455     }
456     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
457     if ((provider != nullptr) && (dCameraStreamOperator_ != nullptr)) {
458         std::vector<int> streamIds = dCameraStreamOperator_->GetStreamIds();
459         provider->StopCapture(dhBase_, streamIds);
460     }
461     if (dCameraStreamOperator_ != nullptr) {
462         dCameraStreamOperator_->Release();
463     }
464 }
465 
NotifyCameraError(const ErrorType type)466 void DCameraDevice::NotifyCameraError(const ErrorType type)
467 {
468     if (dCameraDeviceCallback_ != nullptr) {
469         dCameraDeviceCallback_->OnError(type, 0);
470         Close();
471     }
472 }
473 
SetProviderCallback(const OHOS::sptr<IDCameraProviderCallback> & callback)474 void DCameraDevice::SetProviderCallback(const OHOS::sptr<IDCameraProviderCallback> &callback)
475 {
476     dCameraProviderCallback_ = callback;
477 }
478 
GetProviderCallback()479 OHOS::sptr<IDCameraProviderCallback> DCameraDevice::GetProviderCallback()
480 {
481     return dCameraProviderCallback_;
482 }
483 
GenerateCameraId(const DHBase & dhBase)484 std::string DCameraDevice::GenerateCameraId(const DHBase &dhBase)
485 {
486     return dhBase.deviceId_ + "__" + dhBase.dhId_;
487 }
488 
GetDCameraId()489 std::string DCameraDevice::GetDCameraId()
490 {
491     return dCameraId_;
492 }
493 
IsOpened()494 bool DCameraDevice::IsOpened()
495 {
496     return isOpened_;
497 }
498 } // namespace DistributedHardware
499 } // namespace OHOS
500