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