1 /*
2  * Copyright (c) 2021 - 2023 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 <chrono>
17 #include "camera_device_vdi_impl.h"
18 #include "ipipeline_core.h"
19 #include "camera_host_config.h"
20 #include "idevice_manager.h"
21 #include "camera_metadata_info.h"
22 #include "watchdog.h"
23 #include "metadata_controller.h"
24 #include "metadata_utils.h"
25 #include "camera_dump.h"
26 #ifdef HITRACE_LOG_ENABLED
27 #include "hdf_trace.h"
28 #define HDF_CAMERA_TRACE HdfTrace trace(__func__, "HDI:CAM:")
29 #else
30 #define HDF_CAMERA_TRACE
31 #endif
32 #define HDI_DEVICE_PLACE_A_WATCHDOG \
33     PLACE_A_NOKILL_WATCHDOG(std::bind(&CameraDeviceVdiImpl::OnRequestTimeout, this))
34 
35 namespace OHOS::Camera {
CameraDeviceVdiImpl(const std::string & cameraId,const std::shared_ptr<IPipelineCore> & pipelineCore)36 CameraDeviceVdiImpl::CameraDeviceVdiImpl(const std::string &cameraId,
37     const std::shared_ptr<IPipelineCore> &pipelineCore)
38     : isOpened_(false),
39       cameraId_(cameraId),
40       pipelineCore_(pipelineCore),
41       cameraDeciceCallback_(nullptr),
42       spStreamOperator_(nullptr),
43       metaResultMode_(PER_FRAME),
44       metadataResults_(nullptr)
45 {
46 }
47 
CreateCameraDevice(const std::string & cameraId)48 std::shared_ptr<CameraDeviceVdiImpl> CameraDeviceVdiImpl::CreateCameraDevice(const std::string &cameraId)
49 {
50     HDF_CAMERA_TRACE;
51     // create pipelineCore
52     std::shared_ptr<IPipelineCore> pipelineCore = IPipelineCore::Create();
53     if (pipelineCore == nullptr) {
54         CAMERA_LOGW("create pipeline core failed. [cameraId = %{public}s]", cameraId.c_str());
55         return nullptr;
56     }
57 
58     RetCode rc = pipelineCore->Init();
59     if (rc != RC_OK) {
60         CAMERA_LOGW("pipeline core init failed. [cameraId = %{public}s]", cameraId.c_str());
61         return nullptr;
62     }
63 
64     std::shared_ptr<CameraDeviceVdiImpl> device = std::make_shared<CameraDeviceVdiImpl>(cameraId, pipelineCore);
65     if (device == nullptr) {
66         CAMERA_LOGW("create camera device failed. [cameraId = %{public}s]", cameraId.c_str());
67         return nullptr;
68     }
69     CAMERA_LOGD("create camera device success. [cameraId = %{public}s]", cameraId.c_str());
70 
71     // set deviceManager metadata & dev status callback
72     std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
73     if (deviceManager != nullptr) {
74         deviceManager->SetMetaDataCallBack([device](const std::shared_ptr<CameraMetadata> &metadata) {
75             device->OnMetadataChanged(metadata);
76         });
77         deviceManager->SetDevStatusCallBack([device]() {
78             device->OnDevStatusErr();
79         });
80     }
81 
82     return device;
83 }
84 
GetStreamOperator(const sptr<IStreamOperatorVdiCallback> & callbackObj,sptr<IStreamOperatorVdi> & streamOperator)85 int32_t CameraDeviceVdiImpl::GetStreamOperator(const sptr<IStreamOperatorVdiCallback> &callbackObj,
86     sptr<IStreamOperatorVdi> &streamOperator)
87 {
88     HDF_CAMERA_TRACE;
89     HDI_DEVICE_PLACE_A_WATCHDOG;
90     DFX_LOCAL_HITRACE_BEGIN;
91     if (callbackObj == nullptr) {
92         CAMERA_LOGW("input callback is null.");
93         return INVALID_ARGUMENT;
94     }
95 
96     if (spStreamOperator_ == nullptr) {
97 #ifdef CAMERA_BUILT_ON_OHOS_LITE
98         spStreamOperator_ = std::make_shared<StreamOperatorVdiImpl>(callbackObj, shared_from_this());
99 #else
100         spStreamOperator_ = new(std::nothrow) StreamOperatorVdiImpl(callbackObj, shared_from_this());
101 #endif
102         if (spStreamOperator_ == nullptr) {
103             CAMERA_LOGW("create stream operator failed.");
104             return DEVICE_ERROR;
105         }
106         spStreamOperator_->Init();
107         ismOperator_ = spStreamOperator_;
108     }
109     streamOperator = ismOperator_;
110 #ifndef CAMERA_BUILT_ON_OHOS_LITE
111     InitMetadataController();
112 #endif
113     DFX_LOCAL_HITRACE_END;
114     return VDI::Camera::V1_0::NO_ERROR;
115 }
116 
UpdateSettings(const std::vector<uint8_t> & settings)117 int32_t CameraDeviceVdiImpl::UpdateSettings(const std::vector<uint8_t> &settings)
118 {
119     HDF_CAMERA_TRACE;
120     HDI_DEVICE_PLACE_A_WATCHDOG;
121     DFX_LOCAL_HITRACE_BEGIN;
122     if (settings.empty()) {
123         CAMERA_LOGE("input vector settings is empty.");
124         return INVALID_ARGUMENT;
125     }
126 
127     if (pipelineCore_ == nullptr) {
128         CAMERA_LOGE("pipeline core is null.");
129         return CAMERA_CLOSED;
130     }
131 
132     std::shared_ptr<CameraMetadata> updateSettings;
133     MetadataUtils::ConvertVecToMetadata(settings, updateSettings);
134 
135     CameraDumper &dumper = CameraDumper::GetInstance();
136     dumper.DumpMetadata("updatesetting", ENABLE_METADATA, updateSettings);
137 
138     MetadataController &metaDataController = MetadataController::GetInstance();
139     metaDataController.UpdateSettingsConfig(updateSettings);
140     DFX_LOCAL_HITRACE_END;
141     return VDI::Camera::V1_0::NO_ERROR;
142 }
143 
GetSettings(std::vector<uint8_t> & settings)144 int32_t CameraDeviceVdiImpl::GetSettings(std::vector<uint8_t> &settings)
145 {
146     std::shared_ptr<CameraMetadata> meta = std::make_shared<CameraMetadata>(ENTRY_CAPACITY, DATA_CAPACITY);
147     if (meta == nullptr) {
148         CAMERA_LOGE("meta is nullptr.");
149         return DEVICE_ERROR;
150     }
151     MetadataController &metaDataController = MetadataController::GetInstance();
152     metaDataController.GetSettingsConfig(meta);
153     MetadataUtils::ConvertMetadataToVec(meta, settings);
154     return VDI::Camera::V1_0::NO_ERROR;
155 }
156 
SetResultMode(VdiResultCallbackMode mode)157 int32_t CameraDeviceVdiImpl::SetResultMode(VdiResultCallbackMode mode)
158 {
159     CAMERA_LOGD("entry.");
160     MetadataController &metaDataController = MetadataController::GetInstance();
161     if (mode < PER_FRAME || mode > ON_CHANGED) {
162         CAMERA_LOGE("parameter out of range.");
163         return INVALID_ARGUMENT;
164     } else if (mode == PER_FRAME) {
165         metaDataController.SetPeerFrameFlag(true);
166     } else {
167         metaDataController.SetPeerFrameFlag(false);
168     }
169 
170     metaResultMode_ = mode;
171     return VDI::Camera::V1_0::NO_ERROR;
172 }
173 
GetMetaResultMode() const174 VdiResultCallbackMode CameraDeviceVdiImpl::GetMetaResultMode() const
175 {
176     return metaResultMode_;
177 }
178 
GetEnabledResults(std::vector<int32_t> & results)179 int32_t CameraDeviceVdiImpl::GetEnabledResults(std::vector<int32_t> &results)
180 {
181     HDF_CAMERA_TRACE;
182     HDI_DEVICE_PLACE_A_WATCHDOG;
183     DFX_LOCAL_HITRACE_BEGIN;
184     if (deviceMetaTypes_.empty()) {
185         RetCode rc = GetEnabledFromCfg();
186         if (rc != RC_OK) {
187             CAMERA_LOGE("get enabled results from device manager failed.");
188             return DEVICE_ERROR;
189         }
190     }
191 
192     std::unique_lock<std::mutex> l(enabledRstMutex_);
193     MetadataController &metaDataController = MetadataController::GetInstance();
194     metaDataController.GetEnabledAbility(results);
195     DFX_LOCAL_HITRACE_END;
196     return VDI::Camera::V1_0::NO_ERROR;
197 }
198 
GetEnabledFromCfg()199 RetCode CameraDeviceVdiImpl::GetEnabledFromCfg()
200 {
201     // Get devicemanager
202     std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
203     if (deviceManager == nullptr) {
204         CAMERA_LOGW("device manager is null.");
205         return RC_ERROR;
206     }
207 
208     CameraHostConfig *config = CameraHostConfig::GetInstance();
209     if (config == nullptr) {
210         return RC_ERROR;
211     }
212     std::shared_ptr<CameraMetadata> ability;
213     RetCode rc = config->GetCameraAbility(cameraId_, ability);
214     if (rc != RC_OK || ability == nullptr) {
215         CAMERA_LOGD("GetCameraAbility failed.");
216         return RC_ERROR;
217     }
218 
219     common_metadata_header_t *metadata = ability->get();
220     if (metadata == nullptr) {
221         CAMERA_LOGD("ability get metadata is null.");
222         return RC_ERROR;
223     }
224 
225     camera_metadata_item_t entry;
226     int ret = FindCameraMetadataItem(metadata,
227         OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &entry);
228     if (ret == 0) {
229         CAMERA_LOGD("FindCameraMetadataIte tags = %{public}d. type = %{public}d", entry.count, entry.data_type);
230         for (uint32_t i = 0; i < entry.count; i++) {
231             deviceMetaTypes_.push_back(*(entry.data.i32 + i));
232         }
233     }
234 
235     return RC_OK;
236 }
237 
EnableResult(const std::vector<int32_t> & results)238 int32_t CameraDeviceVdiImpl::EnableResult(const std::vector<int32_t> &results)
239 {
240     HDF_CAMERA_TRACE;
241     HDI_DEVICE_PLACE_A_WATCHDOG;
242     DFX_LOCAL_HITRACE_BEGIN;
243     std::unique_lock<std::mutex> l(enabledRstMutex_);
244     for (auto &metaType : results) {
245         auto itr = std::find(enabledResults_.begin(), enabledResults_.end(), metaType);
246         if (itr == enabledResults_.end()) {
247             enabledResults_.push_back(metaType);
248         } else {
249             CAMERA_LOGW("enabled result is existed. [metaType = %{public}d]", metaType);
250         }
251     }
252     MetadataController &metaDataController = MetadataController::GetInstance();
253     metaDataController.AddEnabledAbility(enabledResults_);
254     DFX_LOCAL_HITRACE_END;
255     return VDI::Camera::V1_0::NO_ERROR;
256 }
257 
DisableResult(const std::vector<int32_t> & results)258 int32_t CameraDeviceVdiImpl::DisableResult(const std::vector<int32_t> &results)
259 {
260     HDF_CAMERA_TRACE;
261     HDI_DEVICE_PLACE_A_WATCHDOG;
262     DFX_LOCAL_HITRACE_BEGIN;
263     VdiCamRetCode ret = VDI::Camera::V1_0::NO_ERROR;
264     std::unique_lock<std::mutex> l(enabledRstMutex_);
265     for (auto &metaType : results) {
266         auto itr = std::find(enabledResults_.begin(), enabledResults_.end(), metaType);
267         if (itr != enabledResults_.end()) {
268             enabledResults_.erase(itr);
269         } else {
270             CAMERA_LOGW("enabled result is not found. [metaType = %{public}d]", metaType);
271             ret = INVALID_ARGUMENT;
272         }
273     }
274     MetadataController &metaDataController = MetadataController::GetInstance();
275     metaDataController.DelEnabledAbility(results);
276     DFX_LOCAL_HITRACE_END;
277     return ret;
278 }
279 
Close()280 int32_t CameraDeviceVdiImpl::Close()
281 {
282     HDI_DEVICE_PLACE_A_WATCHDOG;
283     HDF_CAMERA_TRACE;
284     DFX_LOCAL_HITRACE_BEGIN;
285 
286     MetadataController &metaDataController = MetadataController::GetInstance();
287     metaDataController.Stop();
288     metaDataController.UnSetUpdateSettingCallback();
289 
290     if (spStreamOperator_ != nullptr) {
291         spStreamOperator_->ReleaseStreams();
292         spStreamOperator_ = nullptr;
293     }
294 
295     std::shared_ptr<IDeviceManager> deviceManager = IDeviceManager::GetInstance();
296     if (deviceManager == nullptr) {
297         CAMERA_LOGW("device manager is null [dm name MpiDeviceManager].");
298         return INVALID_ARGUMENT;
299     }
300 
301     CameraHostConfig *config = CameraHostConfig::GetInstance();
302     if (config == nullptr) {
303         CAMERA_LOGD("CameraHostConfig get failed.");
304         return INVALID_ARGUMENT;
305     }
306 
307     std::vector<std::string> phyCameraIds;
308     RetCode rc = config->GetPhysicCameraIds(cameraId_, phyCameraIds);
309     if (rc != RC_OK) {
310         CAMERA_LOGW("get physic cameraId failed.[cameraId = %{public}s]", cameraId_.c_str());
311         return INVALID_ARGUMENT;
312     }
313 
314     for (auto &phyCameraId : phyCameraIds) {
315         auto itr = CameraHostConfig::enumCameraIdMap_.find(phyCameraId);
316         if (itr == CameraHostConfig::enumCameraIdMap_.end()) {
317             CAMERA_LOGW("config phyCameraId undefined in device manager.");
318             continue;
319         }
320 
321         rc = deviceManager->PowerDown(itr->second);
322         if (rc != RC_OK) {
323             CAMERA_LOGE("physic camera powerdown failed [phyCameraId = %{public}s].", phyCameraId.c_str());
324             continue;
325         }
326         CAMERA_LOGD("[phyCameraId = %{public}s] powerdown success.", phyCameraId.c_str());
327     }
328 
329     isOpened_ = false;
330     cameraDeciceCallback_ = nullptr;
331     DFX_LOCAL_HITRACE_END;
332     CAMERA_LOGD("camera close success.");
333     return VDI::Camera::V1_0::NO_ERROR;
334 }
335 
SetCallback(const OHOS::sptr<ICameraDeviceVdiCallback> & callback)336 VdiCamRetCode CameraDeviceVdiImpl::SetCallback(const OHOS::sptr<ICameraDeviceVdiCallback> &callback)
337 {
338     if (callback == nullptr) {
339         return INVALID_ARGUMENT;
340     }
341     cameraDeciceCallback_ = callback;
342     return VDI::Camera::V1_0::NO_ERROR;
343 }
344 
GetPipelineCore() const345 std::shared_ptr<IPipelineCore> CameraDeviceVdiImpl::GetPipelineCore() const
346 {
347     return pipelineCore_;
348 }
349 
GetCurrentLocalTimeStamp()350 uint64_t CameraDeviceVdiImpl::GetCurrentLocalTimeStamp()
351 {
352     std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
353         std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
354     auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
355     return static_cast<uint64_t>(tmp.count());
356 }
357 
InitMetadataController()358 void CameraDeviceVdiImpl::InitMetadataController()
359 {
360     std::shared_ptr<CameraMetadata> meta = std::make_shared<CameraMetadata>(ENTRY_CAPACITY, DATA_CAPACITY);
361     const int32_t deviceStreamId = 0;
362     meta->addEntry(OHOS_CAMERA_STREAM_ID, &deviceStreamId, 1);
363     MetadataController &metaDataController = MetadataController::GetInstance();
364     metaDataController.SetDeviceDefaultMetadata(meta);
365     metaDataController.Start();
366     metaDataController.SetUpdateSettingCallback([this](const std::shared_ptr<CameraMetadata> &metadata) {
367         OnMetadataChanged(metadata);
368     });
369 }
370 
GetCameraId(std::string & cameraId) const371 void CameraDeviceVdiImpl::GetCameraId(std::string &cameraId) const
372 {
373     cameraId = cameraId_;
374 }
375 
OnRequestTimeout()376 void CameraDeviceVdiImpl::OnRequestTimeout()
377 {
378     CAMERA_LOGD("OnRequestTimeout callback success.");
379     // request error
380     cameraDeciceCallback_->OnError(REQUEST_TIMEOUT, 0);
381 }
382 
OnMetadataChanged(const std::shared_ptr<CameraMetadata> & metadata)383 void CameraDeviceVdiImpl::OnMetadataChanged(const std::shared_ptr<CameraMetadata> &metadata)
384 {
385     CAMERA_LOGI("OnMetadataChanged callback success.");
386 
387     if (cameraDeciceCallback_ == nullptr) {
388         CAMERA_LOGE("camera device callback is null.");
389         return;
390     }
391 
392     uint64_t timestamp = GetCurrentLocalTimeStamp();
393     std::vector<uint8_t> result;
394     MetadataUtils::ConvertMetadataToVec(metadata, result);
395 
396     CameraDumper &dumper = CameraDumper::GetInstance();
397     dumper.DumpMetadata("reportmeta", ENABLE_METADATA, metadata);
398 
399     cameraDeciceCallback_->OnResult(timestamp, result);
400 }
401 
OnDevStatusErr()402 void CameraDeviceVdiImpl::OnDevStatusErr()
403 {
404     CAMERA_LOGD("OnDevStatusErr callback success.");
405     // device error
406     cameraDeciceCallback_->OnError(FATAL_ERROR, 0);
407 }
408 
IsOpened() const409 bool CameraDeviceVdiImpl::IsOpened() const
410 {
411     return isOpened_;
412 }
413 
SetStatus(bool isOpened)414 void CameraDeviceVdiImpl::SetStatus(bool isOpened)
415 {
416     isOpened_ = isOpened;
417 }
418 } // end namespace OHOS::Camera
419