• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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