• 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 
GetSettings(std::vector<uint8_t> & settings)146 int32_t DCameraDevice::GetSettings(std::vector<uint8_t> &settings)
147 {
148     if (settings.empty()) {
149         DHLOGE("Get settings failed.");
150         return CamRetCode::DEVICE_ERROR;
151     }
152     return CamRetCode::NO_ERROR;
153 }
154 
SetResultMode(ResultCallbackMode mode)155 int32_t DCameraDevice::SetResultMode(ResultCallbackMode mode)
156 {
157     if (dMetadataProcessor_ == nullptr) {
158         DHLOGE("Metadata processor not init.");
159         return CamRetCode::DEVICE_ERROR;
160     }
161 
162     DCamRetCode ret = dMetadataProcessor_->SetMetadataResultMode(mode);
163     if (ret != SUCCESS) {
164         DHLOGE("Set metadata result mode failed, ret=%d.", ret);
165     }
166     return MapToExternalRetCode(ret);
167 }
168 
GetEnabledResults(std::vector<int32_t> & results)169 int32_t DCameraDevice::GetEnabledResults(std::vector<int32_t> &results)
170 {
171     if (dMetadataProcessor_ == nullptr) {
172         DHLOGE("Metadata processor not init.");
173         return CamRetCode::DEVICE_ERROR;
174     }
175 
176     DCamRetCode ret = dMetadataProcessor_->GetEnabledMetadataResults(results);
177     if (ret != SUCCESS) {
178         DHLOGE("Get enabled metadata results failed, ret=%d.", ret);
179     }
180     return MapToExternalRetCode(ret);
181 }
182 
EnableResult(const std::vector<int32_t> & results)183 int32_t DCameraDevice::EnableResult(const std::vector<int32_t> &results)
184 {
185     if (results.empty() || results.size() > METADATA_CAPACITY_MAX_SIZE) {
186         DHLOGE("DCameraDevice::EnableResult, input results is invalid.");
187         return CamRetCode::DEVICE_ERROR;
188     }
189 
190     if (dMetadataProcessor_ == nullptr) {
191         DHLOGE("Metadata processor not init.");
192         return CamRetCode::DEVICE_ERROR;
193     }
194 
195     DCamRetCode ret = dMetadataProcessor_->EnableMetadataResult(results);
196     if (ret != SUCCESS) {
197         DHLOGE("Enable metadata result failed, ret=%d.", ret);
198         return MapToExternalRetCode(ret);
199     }
200 
201     stringstream sstream;
202     std::reverse_copy(results.begin(), results.end(), ostream_iterator<int32_t>(sstream, ""));
203     DCameraSettings dcSetting;
204     dcSetting.type_ = DCSettingsType::ENABLE_METADATA;
205     dcSetting.value_ = sstream.str();
206 
207     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
208     if (provider == nullptr) {
209         DHLOGE("Enable metadata failed, provider is nullptr.");
210         return CamRetCode::DEVICE_ERROR;
211     }
212     std::vector<DCameraSettings> dcSettings;
213     dcSettings.push_back(dcSetting);
214     int32_t retProv = provider->UpdateSettings(dhBase_, dcSettings);
215     return MapToExternalRetCode(static_cast<DCamRetCode>(retProv));
216 }
217 
DisableResult(const std::vector<int32_t> & results)218 int32_t DCameraDevice::DisableResult(const std::vector<int32_t> &results)
219 {
220     if (results.empty() || results.size() > METADATA_CAPACITY_MAX_SIZE) {
221         DHLOGE("DCameraDevice::DisableResult, input results is invalid.");
222         return CamRetCode::DEVICE_ERROR;
223     }
224 
225     if (dMetadataProcessor_ == nullptr) {
226         DHLOGE("Metadata processor not init.");
227         return CamRetCode::DEVICE_ERROR;
228     }
229 
230     DCamRetCode ret = dMetadataProcessor_->DisableMetadataResult(results);
231     if (ret != SUCCESS) {
232         DHLOGE("Disable metadata result failed, ret=%d.", ret);
233         return MapToExternalRetCode(ret);
234     }
235 
236     stringstream sstream;
237     std::reverse_copy(results.begin(), results.end(), ostream_iterator<int32_t>(sstream, ""));
238     DCameraSettings dcSetting;
239     dcSetting.type_ = DCSettingsType::DISABLE_METADATA;
240     dcSetting.value_ = sstream.str();
241 
242     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
243     if (provider == nullptr) {
244         DHLOGE("Metadata processor provider is nullptr.");
245         return CamRetCode::DEVICE_ERROR;
246     }
247     std::vector<DCameraSettings> dcSettings;
248     dcSettings.push_back(dcSetting);
249     int32_t retProv = provider->UpdateSettings(dhBase_, dcSettings);
250     return MapToExternalRetCode(static_cast<DCamRetCode>(retProv));
251 }
252 
Close()253 int32_t DCameraDevice::Close()
254 {
255     DHLOGI("DCameraDevice::Close distributed camera: %s", GetAnonyString(dCameraId_).c_str());
256 
257     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
258     if ((provider != nullptr) && (dCameraStreamOperator_ != nullptr)) {
259         std::vector<int> streamIds = dCameraStreamOperator_->GetStreamIds();
260         provider->StopCapture(dhBase_, streamIds);
261     }
262     if (dCameraStreamOperator_ != nullptr) {
263         dCameraStreamOperator_->Release();
264         dCameraStreamOperator_ = nullptr;
265     }
266     if (provider != nullptr) {
267         provider->CloseSession(dhBase_);
268     }
269     if (dMetadataProcessor_ != nullptr) {
270         dMetadataProcessor_->ResetEnableResults();
271     }
272     dCameraDeviceCallback_ = nullptr;
273     isOpenSessFailed_ = false;
274     isOpened_ = false;
275     return CamRetCode::NO_ERROR;
276 }
277 
OpenDCamera(const OHOS::sptr<ICameraDeviceCallback> & callback)278 CamRetCode DCameraDevice::OpenDCamera(const OHOS::sptr<ICameraDeviceCallback> &callback)
279 {
280     if (callback == nullptr) {
281         DHLOGE("Input callback is null.");
282         return CamRetCode::INVALID_ARGUMENT;
283     }
284     dCameraDeviceCallback_ = callback;
285 
286     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
287     if (provider == nullptr) {
288         DHLOGE("Get distributed camera provider instance is null.");
289         return CamRetCode::DEVICE_ERROR;
290     }
291     int32_t ret = provider->OpenSession(dhBase_);
292     if (ret != DCamRetCode::SUCCESS) {
293         DHLOGE("Open distributed camera control session failed, ret = %d.", ret);
294         return MapToExternalRetCode(static_cast<DCamRetCode>(ret));
295     }
296 
297     unique_lock<mutex> lock(openSesslock_);
298     auto st = openSessCV_.wait_for(lock, chrono::seconds(WAIT_OPEN_TIMEOUT_SEC));
299     if (st == cv_status::timeout) {
300         DHLOGE("Wait for distributed camera session open timeout.");
301         return CamRetCode::DEVICE_ERROR;
302     }
303     {
304         unique_lock<mutex> openStateLock(isOpenSessFailedlock_);
305         if (isOpenSessFailed_) {
306             DHLOGE("Open distributed camera session failed.");
307             return CamRetCode::DEVICE_ERROR;
308         }
309     }
310 
311     DCamRetCode retDCode = CreateDStreamOperator();
312     if (ret != SUCCESS) {
313         DHLOGE("Create distributed camera stream operator failed.");
314         return MapToExternalRetCode(retDCode);
315     }
316     isOpened_ = true;
317 
318     return MapToExternalRetCode(retDCode);
319 }
320 
GetDCameraAbility(std::shared_ptr<CameraAbility> & ability)321 CamRetCode DCameraDevice::GetDCameraAbility(std::shared_ptr<CameraAbility> &ability)
322 {
323     if (dMetadataProcessor_ == nullptr) {
324         DHLOGE("Metadata processor not init.");
325         return CamRetCode::DEVICE_ERROR;
326     }
327 
328     DCamRetCode ret = dMetadataProcessor_->GetDCameraAbility(ability);
329     if (ret != SUCCESS) {
330         DHLOGE("Get distributed camera ability failed, ret=%d.", ret);
331     }
332     return MapToExternalRetCode(ret);
333 }
334 
AcquireBuffer(int streamId,DCameraBuffer & buffer)335 DCamRetCode DCameraDevice::AcquireBuffer(int streamId, DCameraBuffer &buffer)
336 {
337     if (dCameraStreamOperator_ == nullptr) {
338         DHLOGE("Stream operator not init.");
339         return DEVICE_NOT_INIT;
340     }
341 
342     DCamRetCode ret = dCameraStreamOperator_->AcquireBuffer(streamId, buffer);
343     if (ret != SUCCESS) {
344         DHLOGE("Acquire buffer failed, ret=%d.", ret);
345     }
346     return ret;
347 }
348 
ShutterBuffer(int streamId,const DCameraBuffer & buffer)349 DCamRetCode DCameraDevice::ShutterBuffer(int streamId, const DCameraBuffer &buffer)
350 {
351     if (dCameraStreamOperator_ == nullptr) {
352         DHLOGE("Stream operator not init.");
353         return DEVICE_NOT_INIT;
354     }
355 
356     DCamRetCode ret = dCameraStreamOperator_->ShutterBuffer(streamId, buffer);
357     if (ret != SUCCESS) {
358         DHLOGE("Shutter buffer failed, ret=%d.", ret);
359     }
360     return ret;
361 }
362 
OnSettingsResult(const std::shared_ptr<DCameraSettings> & result)363 DCamRetCode DCameraDevice::OnSettingsResult(const std::shared_ptr<DCameraSettings> &result)
364 {
365     if (result == nullptr) {
366         DHLOGE("Input camera settings is null.");
367         return DCamRetCode::INVALID_ARGUMENT;
368     }
369 
370     if (dMetadataProcessor_ == nullptr) {
371         DHLOGE("Metadata processor not init.");
372         return DCamRetCode::DEVICE_NOT_INIT;
373     }
374 
375     if (result->type_ != DCSettingsType::METADATA_RESULT) {
376         DHLOGE("Invalid camera setting type = %d.", result->type_);
377         return DCamRetCode::INVALID_ARGUMENT;
378     }
379     if ((result->value_).empty()) {
380         DHLOGE("Camera settings result is empty.");
381         return DCamRetCode::INVALID_ARGUMENT;
382     }
383 
384     DCamRetCode ret = dMetadataProcessor_->SaveResultMetadata(result->value_);
385     if (ret != DCamRetCode::SUCCESS) {
386         DHLOGE("Save result metadata failed, ret = %d", ret);
387     }
388     return ret;
389 }
390 
Notify(const std::shared_ptr<DCameraHDFEvent> & event)391 DCamRetCode DCameraDevice::Notify(const std::shared_ptr<DCameraHDFEvent> &event)
392 {
393     DHLOGI("DCameraDevice::Notify for event type = %d, result = %d, content = %s.", event->type_, event->result_,
394         event->content_.c_str());
395     if ((event->type_ != DCameraEventType::DCAMERA_MESSAGE) && (event->type_ != DCameraEventType::DCAMERA_OPERATION)) {
396         DHLOGE("Invalid distributed camera event type = %d.", event->type_);
397         return DCamRetCode::INVALID_ARGUMENT;
398     }
399     switch (event->result_) {
400         case DCameraEventResult::DCAMERA_EVENT_CHANNEL_CONNECTED: {
401             IsOpenSessFailedState(false);
402             break;
403         }
404         case DCameraEventResult::DCAMERA_EVENT_OPEN_CHANNEL_ERROR: {
405             IsOpenSessFailedState(true);
406             break;
407         }
408         case DCameraEventResult::DCAMERA_EVENT_CHANNEL_DISCONNECTED: {
409             NotifyCameraError(ErrorType::DEVICE_DISCONNECT);
410             break;
411         }
412         case DCameraEventResult::DCAMERA_EVENT_CONFIG_STREAMS_ERROR:
413         case DCameraEventResult::DCAMERA_EVENT_START_CAPTURE_ERROR: {
414             NotifyStartCaptureError();
415             break;
416         }
417         case DCameraEventResult::DCAMERA_EVENT_DEVICE_ERROR: {
418             NotifyCameraError(ErrorType::DRIVER_ERROR);
419             break;
420         }
421         case DCameraEventResult::DCAMERA_EVENT_DEVICE_PREEMPT: {
422             NotifyCameraError(ErrorType::DEVICE_PREEMPT);
423             break;
424         }
425         case DCameraEventResult::DCAMERA_EVENT_DEVICE_IN_USE: {
426             NotifyCameraError(ErrorType::DCAMERA_ERROR_DEVICE_IN_USE);
427             break;
428         }
429         case DCameraEventResult::DCAMERA_EVENT_NO_PERMISSION: {
430             NotifyCameraError(ErrorType::DCAMERA_ERROR_NO_PERMISSION);
431             break;
432         }
433         default:
434             break;
435     }
436     return SUCCESS;
437 }
438 
IsOpenSessFailedState(bool state)439 void DCameraDevice::IsOpenSessFailedState(bool state)
440 {
441     {
442         unique_lock<mutex> lock(isOpenSessFailedlock_);
443         isOpenSessFailed_ = state;
444     }
445     openSessCV_.notify_one();
446 }
447 
NotifyStartCaptureError()448 void DCameraDevice::NotifyStartCaptureError()
449 {
450     if (dCameraDeviceCallback_ != nullptr) {
451         dCameraDeviceCallback_->OnError(ErrorType::REQUEST_TIMEOUT, 0);
452     }
453     OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
454     if ((provider != nullptr) && (dCameraStreamOperator_ != nullptr)) {
455         std::vector<int> streamIds = dCameraStreamOperator_->GetStreamIds();
456         provider->StopCapture(dhBase_, streamIds);
457     }
458     if (dCameraStreamOperator_ != nullptr) {
459         dCameraStreamOperator_->Release();
460     }
461 }
462 
NotifyCameraError(const ErrorType type)463 void DCameraDevice::NotifyCameraError(const ErrorType type)
464 {
465     if (dCameraDeviceCallback_ != nullptr) {
466         dCameraDeviceCallback_->OnError(type, 0);
467         Close();
468     }
469 }
470 
SetProviderCallback(const OHOS::sptr<IDCameraProviderCallback> & callback)471 void DCameraDevice::SetProviderCallback(const OHOS::sptr<IDCameraProviderCallback> &callback)
472 {
473     dCameraProviderCallback_ = callback;
474 }
475 
GetProviderCallback()476 OHOS::sptr<IDCameraProviderCallback> DCameraDevice::GetProviderCallback()
477 {
478     return dCameraProviderCallback_;
479 }
480 
GenerateCameraId(const DHBase & dhBase)481 std::string DCameraDevice::GenerateCameraId(const DHBase &dhBase)
482 {
483     return dhBase.deviceId_ + "__" + dhBase.dhId_;
484 }
485 
GetDCameraId()486 std::string DCameraDevice::GetDCameraId()
487 {
488     return dCameraId_;
489 }
490 
IsOpened()491 bool DCameraDevice::IsOpened()
492 {
493     return isOpened_;
494 }
495 } // namespace DistributedHardware
496 } // namespace OHOS
497