1 /*
2 * Copyright (c) 2021-2025 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_provider.h"
17 #include "anonymous_string.h"
18 #include "constants.h"
19 #include "dcamera_device.h"
20 #include "dcamera_host.h"
21 #include "distributed_hardware_log.h"
22 #include "dcamera.h"
23
24 namespace OHOS {
25 namespace DistributedHardware {
26 OHOS::sptr<DCameraProvider> DCameraProvider::instance_ = nullptr;
27 DCameraProvider::AutoRelease DCameraProvider::autoRelease_;
28
HdiImplGetInstance(void)29 extern "C" IDCameraProvider *HdiImplGetInstance(void)
30 {
31 return static_cast<IDCameraProvider *>(DCameraProvider::GetInstance().GetRefPtr());
32 }
33
GetInstance()34 OHOS::sptr<DCameraProvider> DCameraProvider::GetInstance()
35 {
36 if (instance_ == nullptr) {
37 instance_ = sptr<DCameraProvider>(new DCameraProvider());
38 if (instance_ == nullptr) {
39 DHLOGE("Get distributed camera provider instance failed.");
40 return nullptr;
41 }
42 }
43 return instance_;
44 }
45
GetAbilityInfo(const std::string & abilityInfo,std::string & sinkAbilityInfo,std::string & sourceCodecInfo)46 bool DCameraProvider::GetAbilityInfo(const std::string& abilityInfo, std::string& sinkAbilityInfo,
47 std::string& sourceCodecInfo)
48 {
49 cJSON *rootValue = cJSON_Parse(abilityInfo.c_str());
50 CHECK_NULL_RETURN_LOG(rootValue, false, "The abilityInfo is null.");
51 CHECK_OBJECT_FREE_RETURN(rootValue, false, "The abilityInfo is not object.");
52
53 cJSON *sinkRootValue = cJSON_GetObjectItemCaseSensitive(rootValue, "SinkAbility");
54 if (sinkRootValue == nullptr || !cJSON_IsObject(sinkRootValue)) {
55 cJSON_Delete(rootValue);
56 DHLOGE("Get sink ability error.");
57 return false;
58 }
59
60 cJSON *srcRootValue = cJSON_GetObjectItemCaseSensitive(rootValue, "SourceCodec");
61 if (srcRootValue == nullptr || !cJSON_IsObject(srcRootValue)) {
62 cJSON_Delete(rootValue);
63 DHLOGE("Get source ability error.");
64 return false;
65 }
66
67 char *jsonSink = cJSON_Print(sinkRootValue);
68 if (jsonSink == nullptr) {
69 cJSON_Delete(rootValue);
70 return false;
71 }
72 sinkAbilityInfo = std::string(jsonSink);
73
74 char *jsonSource = cJSON_Print(srcRootValue);
75 if (jsonSource == nullptr) {
76 cJSON_Delete(rootValue);
77 cJSON_free(jsonSink);
78 return false;
79 }
80 sourceCodecInfo = std::string(jsonSource);
81 cJSON_Delete(rootValue);
82 cJSON_free(jsonSink);
83 cJSON_free(jsonSource);
84 return true;
85 }
86
EnableDCameraDevice(const DHBase & dhBase,const std::string & abilityInfo,const sptr<IDCameraProviderCallback> & callbackObj)87 int32_t DCameraProvider::EnableDCameraDevice(const DHBase& dhBase, const std::string& abilityInfo,
88 const sptr<IDCameraProviderCallback>& callbackObj)
89 {
90 if (IsDhBaseInfoInvalid(dhBase)) {
91 DHLOGE("DCameraProvider::EnableDCameraDevice, devId or dhId is invalid.");
92 return DCamRetCode::INVALID_ARGUMENT;
93 }
94 DHLOGI("DCameraProvider::EnableDCameraDevice for {devId: %{public}s, dhId: %{public}s, sinkAbilityInfo length: "
95 "%{public}zu}.", GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str(),
96 abilityInfo.length());
97 if (abilityInfo.empty() || abilityInfo.length() > ABILITYINFO_MAX_LENGTH) {
98 DHLOGE("DCameraProvider::EnableDCameraDevice, dcamera ability is empty or over limit.");
99 return DCamRetCode::INVALID_ARGUMENT;
100 }
101 if (callbackObj == nullptr) {
102 DHLOGE("DCameraProvider::EnableDCameraDevice, dcamera provider callback is null.");
103 return DCamRetCode::INVALID_ARGUMENT;
104 }
105
106 OHOS::sptr<DCameraHost> dCameraHost = DCameraHost::GetInstance();
107 if (dCameraHost == nullptr) {
108 DHLOGE("DCameraProvider::EnableDCameraDevice, dcamera host is null.");
109 return DCamRetCode::DEVICE_NOT_INIT;
110 }
111 std::string sourceCodecInfo;
112 std::string sinkAbilityInfo;
113 if (!GetAbilityInfo(abilityInfo, sinkAbilityInfo, sourceCodecInfo)) {
114 return DCamRetCode::INVALID_ARGUMENT;
115 }
116
117 DCamRetCode ret = dCameraHost->AddDCameraDevice(dhBase, sinkAbilityInfo, sourceCodecInfo, callbackObj);
118 if (ret != DCamRetCode::SUCCESS) {
119 DHLOGE("DCameraProvider::EnableDCameraDevice failed, ret = %{public}d.", ret);
120 }
121 return ret;
122 }
123
DisableDCameraDevice(const DHBase & dhBase)124 int32_t DCameraProvider::DisableDCameraDevice(const DHBase& dhBase)
125 {
126 if (IsDhBaseInfoInvalid(dhBase)) {
127 DHLOGE("DCameraProvider::DisableDCameraDevice, devId or dhId is invalid.");
128 return DCamRetCode::INVALID_ARGUMENT;
129 }
130 DHLOGI("DCameraProvider::DisableDCameraDevice for {devId: %{public}s, dhId: %{public}s}.",
131 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
132
133 OHOS::sptr<DCameraHost> dCameraHost = DCameraHost::GetInstance();
134 if (dCameraHost == nullptr) {
135 DHLOGE("DCameraProvider::DisableDCameraDevice, dcamera host is null.");
136 return DCamRetCode::DEVICE_NOT_INIT;
137 }
138 DCamRetCode ret = dCameraHost->RemoveDCameraDevice(dhBase);
139 if (ret != DCamRetCode::SUCCESS) {
140 DHLOGE("DCameraProvider::DisableDCameraDevice failed, ret = %{public}d.", ret);
141 return ret;
142 }
143
144 return DCamRetCode::SUCCESS;
145 }
146
AcquireBuffer(const DHBase & dhBase,int32_t streamId,DCameraBuffer & buffer)147 int32_t DCameraProvider::AcquireBuffer(const DHBase& dhBase, int32_t streamId, DCameraBuffer& buffer)
148 {
149 if (IsDhBaseInfoInvalid(dhBase)) {
150 DHLOGE("DCameraProvider::AcquireBuffer, devId or dhId is invalid.");
151 return DCamRetCode::INVALID_ARGUMENT;
152 }
153 if (streamId < 0) {
154 DHLOGE("DCameraProvider::AcquireBuffer, input streamId is invalid.");
155 return DCamRetCode::INVALID_ARGUMENT;
156 }
157
158 DHLOGD("DCameraProvider::AcquireBuffer for {devId: %{public}s, dhId: %{public}s}, streamId: %{public}d.",
159 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str(), streamId);
160
161 OHOS::sptr<DCameraDevice> device = GetDCameraDevice(dhBase);
162 if (device == nullptr) {
163 DHLOGE("DCameraProvider::AcquireBuffer failed, dcamera device not found.");
164 return DCamRetCode::INVALID_ARGUMENT;
165 }
166
167 DCamRetCode ret = device->AcquireBuffer(streamId, buffer);
168 if (ret != DCamRetCode::SUCCESS) {
169 DHLOGE("DCameraProvider::AcquireBuffer failed, ret = %{public}d.", ret);
170 return ret;
171 }
172 return DCamRetCode::SUCCESS;
173 }
174
ShutterBuffer(const DHBase & dhBase,int32_t streamId,const DCameraBuffer & buffer)175 int32_t DCameraProvider::ShutterBuffer(const DHBase& dhBase, int32_t streamId, const DCameraBuffer& buffer)
176 {
177 if (IsDhBaseInfoInvalid(dhBase)) {
178 DHLOGE("DCameraProvider::ShutterBuffer, devId or dhId is invalid.");
179 return DCamRetCode::INVALID_ARGUMENT;
180 }
181 if (buffer.index_ < 0 || buffer.size_ < 0) {
182 DHLOGE("DCameraProvider::ShutterBuffer, input dcamera buffer is invalid.");
183 return DCamRetCode::INVALID_ARGUMENT;
184 }
185 if (streamId < 0) {
186 DHLOGE("DCameraProvider::ShutterBuffer, input streamId is invalid.");
187 return DCamRetCode::INVALID_ARGUMENT;
188 }
189
190 DHLOGD("DCameraProvider::ShutterBuffer for {devId: %{public}s, dhId: %{public}s}, streamId = %{public}d, "
191 "buffer index = %{public}d.",
192 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str(), streamId, buffer.index_);
193 OHOS::sptr<DCameraDevice> device = GetDCameraDevice(dhBase);
194 if (device == nullptr) {
195 DHLOGE("DCameraProvider::ShutterBuffer failed, dcamera device not found.");
196 return DCamRetCode::INVALID_ARGUMENT;
197 }
198 return device->ShutterBuffer(streamId, buffer);
199 }
200
OnSettingsResult(const DHBase & dhBase,const DCameraSettings & result)201 int32_t DCameraProvider::OnSettingsResult(const DHBase& dhBase, const DCameraSettings& result)
202 {
203 if (IsDhBaseInfoInvalid(dhBase)) {
204 DHLOGE("DCameraProvider::OnSettingsResult, devId or dhId is invalid.");
205 return DCamRetCode::INVALID_ARGUMENT;
206 }
207 if (IsDCameraSettingsInvalid(result)) {
208 DHLOGE("DCameraProvider::OnSettingsResult, input dcamera settings is valid.");
209 return DCamRetCode::INVALID_ARGUMENT;
210 }
211 DHLOGI("DCameraProvider::OnSettingsResult for {devId: %{public}s, dhId: %{public}s}.",
212 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
213
214 OHOS::sptr<DCameraDevice> device = GetDCameraDevice(dhBase);
215 if (device == nullptr) {
216 DHLOGE("DCameraProvider::OnSettingsResult failed, dcamera device not found.");
217 return DCamRetCode::INVALID_ARGUMENT;
218 }
219
220 std::shared_ptr<DCameraSettings> dCameraResult = std::make_shared<DCameraSettings>();
221 dCameraResult->type_ = result.type_;
222 dCameraResult->value_ = result.value_;
223 return device->OnSettingsResult(dCameraResult);
224 }
225
Notify(const DHBase & dhBase,const DCameraHDFEvent & event)226 int32_t DCameraProvider::Notify(const DHBase& dhBase, const DCameraHDFEvent& event)
227 {
228 if (IsDhBaseInfoInvalid(dhBase)) {
229 DHLOGE("DCameraProvider::Notify, devId or dhId is invalid.");
230 return DCamRetCode::INVALID_ARGUMENT;
231 }
232 if (IsDCameraHDFEventInvalid(event)) {
233 DHLOGE("DCameraProvider::Notify, input dcamera hdf event is null.");
234 return DCamRetCode::INVALID_ARGUMENT;
235 }
236 DHLOGI("DCameraProvider::Notify for {devId: %{public}s, dhId: %{public}s}.",
237 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
238
239 OHOS::sptr<DCameraDevice> device = GetDCameraDevice(dhBase);
240 if (device == nullptr) {
241 DHLOGE("DCameraProvider::Notify failed, dcamera device not found.");
242 return DCamRetCode::INVALID_ARGUMENT;
243 }
244
245 std::shared_ptr<DCameraHDFEvent> dCameraEvent = std::make_shared<DCameraHDFEvent>();
246 dCameraEvent->type_ = event.type_;
247 dCameraEvent->result_ = event.result_;
248 dCameraEvent->content_ = event.content_;
249 return device->Notify(dCameraEvent);
250 }
251
RegisterCameraHdfListener(const std::string & serviceName,const sptr<IDCameraHdfCallback> & callbackObj)252 int32_t DCameraProvider::RegisterCameraHdfListener(const std::string &serviceName,
253 const sptr<IDCameraHdfCallback> &callbackObj)
254 {
255 DHLOGI("Register camera HDF listener, serviceName: %{public}s.", GetAnonyString(serviceName).c_str());
256 if (callbackObj == nullptr) {
257 DHLOGE("dcamera hdf callback is null.");
258 return DCamRetCode::INVALID_ARGUMENT;
259 }
260 OHOS::sptr<DCameraHost> dCameraHost = DCameraHost::GetInstance();
261 if (dCameraHost == nullptr) {
262 DHLOGE("dcamera host is null.");
263 return DCamRetCode::DEVICE_NOT_INIT;
264 }
265 auto ret = dCameraHost->RegisterCameraHdfListener(serviceName, callbackObj);
266 if (ret != DCamRetCode::SUCCESS) {
267 DHLOGE("call dcamera host RegisterCameraHdfListener failed, ret = %{public}d.", ret);
268 return ret;
269 }
270 DHLOGI("Register camera HDF listener success.");
271 return DCamRetCode::SUCCESS;
272 }
273
UnRegisterCameraHdfListener(const std::string & serviceName)274 int32_t DCameraProvider::UnRegisterCameraHdfListener(const std::string &serviceName)
275 {
276 DHLOGI("Unregister camera HDF listener, serviceName: %{public}s.", GetAnonyString(serviceName).c_str());
277 OHOS::sptr<DCameraHost> dCameraHost = DCameraHost::GetInstance();
278 if (dCameraHost == nullptr) {
279 DHLOGE("dcamera host is null.");
280 return DCamRetCode::DEVICE_NOT_INIT;
281 }
282 auto ret = dCameraHost->UnRegisterCameraHdfListener(serviceName);
283 if (ret != DCamRetCode::SUCCESS) {
284 DHLOGE("call dcamera host UnRegisterCameraHdfListener failed, ret = %{public}d.", ret);
285 return ret;
286 }
287 DHLOGI("Unregister camera HDF listener success.");
288 return DCamRetCode::SUCCESS;
289 }
290
OpenSession(const DHBase & dhBase)291 int32_t DCameraProvider::OpenSession(const DHBase &dhBase)
292 {
293 DHLOGI("DCameraProvider::OpenSession for {devId: %{public}s, dhId: %{public}s}.",
294 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
295
296 sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
297 if (callback == nullptr) {
298 DHLOGE("DCameraProvider::OpenSession, dcamera provider callback not found.");
299 return DCamRetCode::INVALID_ARGUMENT;
300 }
301
302 return callback->OpenSession(dhBase);
303 }
304
CloseSession(const DHBase & dhBase)305 int32_t DCameraProvider::CloseSession(const DHBase &dhBase)
306 {
307 DHLOGI("DCameraProvider::CloseSession for {devId: %{public}s, dhId: %{public}s}.",
308 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
309
310 sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
311 if (callback == nullptr) {
312 DHLOGE("DCameraProvider::CloseSession, dcamera provider callback not found.");
313 return DCamRetCode::INVALID_ARGUMENT;
314 }
315
316 return callback->CloseSession(dhBase);
317 }
318
ConfigureStreams(const DHBase & dhBase,const std::vector<DCStreamInfo> & streamInfos)319 int32_t DCameraProvider::ConfigureStreams(const DHBase &dhBase, const std::vector<DCStreamInfo> &streamInfos)
320 {
321 DHLOGI("DCameraProvider::ConfigureStreams for {devId: %{public}s, dhId: %{public}s}.",
322 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
323
324 sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
325 if (callback == nullptr) {
326 DHLOGE("DCameraProvider::ConfigStreams, dcamera provider callback not found.");
327 return DCamRetCode::INVALID_ARGUMENT;
328 }
329
330 for (auto info = streamInfos.begin(); info != streamInfos.end(); info++) {
331 DHLOGI("ConfigureStreams: id=%{public}d, width=%{public}d, height=%{public}d, format=%{public}d, "
332 "type=%{public}d, mode=%{public}d.", info->streamId_, info->width_, info->height_, info->format_,
333 info->type_, info->mode_);
334 }
335 return callback->ConfigureStreams(dhBase, streamInfos);
336 }
337
ReleaseStreams(const DHBase & dhBase,const std::vector<int> & streamIds)338 int32_t DCameraProvider::ReleaseStreams(const DHBase &dhBase, const std::vector<int> &streamIds)
339 {
340 DHLOGI("DCameraProvider::ReleaseStreams for {devId: %{public}s, dhId: %{public}s}.",
341 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
342
343 sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
344 if (callback == nullptr) {
345 DHLOGE("DCameraProvider::ReleaseStreams, dcamera provider callback not found.");
346 return DCamRetCode::INVALID_ARGUMENT;
347 }
348
349 std::string idString = "";
350 for (int id : streamIds) {
351 idString += (std::to_string(id) + ", ");
352 }
353 DHLOGI("ReleaseStreams: ids=[%{public}s].", idString.c_str());
354 return callback->ReleaseStreams(dhBase, streamIds);
355 }
356
StartCapture(const DHBase & dhBase,const std::vector<DCCaptureInfo> & captureInfos)357 int32_t DCameraProvider::StartCapture(const DHBase &dhBase, const std::vector<DCCaptureInfo> &captureInfos)
358 {
359 DHLOGI("DCameraProvider::StartCapture for {devId: %{public}s, dhId: %{public}s}.",
360 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
361
362 sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
363 if (callback == nullptr) {
364 DHLOGE("DCameraProvider::StartCapture, dcamera provider callback not found.");
365 return DCamRetCode::INVALID_ARGUMENT;
366 }
367
368 for (auto info = captureInfos.begin(); info != captureInfos.end(); info++) {
369 std::string idString = "";
370 for (int id : info->streamIds_) {
371 idString += (std::to_string(id) + ", ");
372 }
373 DHLOGI("DCameraProvider::StartCapture: ids=[%{public}s], width=%{public}d, height=%{public}d, format="
374 "%{public}d, type=%{public}d, isCapture=%{public}d.",
375 (idString.empty() ? idString.c_str() : (idString.substr(0, idString.length() - INGNORE_STR_LEN)).c_str()),
376 info->width_, info->height_, info->format_, info->type_, info->isCapture_);
377 }
378 return callback->StartCapture(dhBase, captureInfos);
379 }
380
StopCapture(const DHBase & dhBase,const std::vector<int> & streamIds)381 int32_t DCameraProvider::StopCapture(const DHBase &dhBase, const std::vector<int> &streamIds)
382 {
383 DHLOGI("DCameraProvider::StopCapture for {devId: %{public}s, dhId: %{public}s}.",
384 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
385
386 sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
387 if (callback == nullptr) {
388 DHLOGE("DCameraProvider::StopCapture, dcamera provider callback not found.");
389 return DCamRetCode::INVALID_ARGUMENT;
390 }
391
392 std::string idString = "";
393 for (int id : streamIds) {
394 idString += (std::to_string(id) + ", ");
395 }
396 DHLOGI("DCameraProvider::StopCapture: ids=[%{public}s].",
397 idString.empty() ? idString.c_str() : (idString.substr(0, idString.length() - INGNORE_STR_LEN)).c_str());
398 return callback->StopCapture(dhBase, streamIds);
399 }
400
UpdateSettings(const DHBase & dhBase,const std::vector<DCameraSettings> & settings)401 int32_t DCameraProvider::UpdateSettings(const DHBase &dhBase, const std::vector<DCameraSettings> &settings)
402 {
403 DHLOGI("DCameraProvider::UpdateSettings for {devId: %{public}s, dhId: %{public}s}.",
404 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
405
406 sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
407 if (callback == nullptr) {
408 DHLOGE("DCameraProvider::UpdateSettings, dcamera provider callback not found.");
409 return DCamRetCode::INVALID_ARGUMENT;
410 }
411
412 return callback->UpdateSettings(dhBase, settings);
413 }
414
IsDCameraSettingsInvalid(const DCameraSettings & result)415 bool DCameraProvider::IsDCameraSettingsInvalid(const DCameraSettings& result)
416 {
417 return result.value_.empty() || result.value_.length() > SETTING_VALUE_MAX_LENGTH;
418 }
419
IsDCameraHDFEventInvalid(const DCameraHDFEvent & event)420 bool DCameraProvider::IsDCameraHDFEventInvalid(const DCameraHDFEvent& event)
421 {
422 return event.content_.length() > HDF_EVENT_CONTENT_MAX_LENGTH;
423 }
424
GetCallbackBydhBase(const DHBase & dhBase)425 sptr<IDCameraProviderCallback> DCameraProvider::GetCallbackBydhBase(const DHBase &dhBase)
426 {
427 OHOS::sptr<DCameraDevice> device = GetDCameraDevice(dhBase);
428 if (device == nullptr) {
429 DHLOGE("DCameraProvider::GetCallbackBydhBase failed, dcamera device not found.");
430 return nullptr;
431 }
432 return device->GetProviderCallback();
433 }
434
GetDCameraDevice(const DHBase & dhBase)435 OHOS::sptr<DCameraDevice> DCameraProvider::GetDCameraDevice(const DHBase &dhBase)
436 {
437 OHOS::sptr<DCameraHost> dCameraHost = DCameraHost::GetInstance();
438 if (dCameraHost == nullptr) {
439 DHLOGE("DCameraProvider::GetDCameraDevice, dcamera host is null.");
440 return nullptr;
441 }
442 return dCameraHost->GetDCameraDeviceByDHBase(dhBase);
443 }
444 } // namespace DistributedHardware
445 } // namespace OHOS
446