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