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