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