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_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 
OpenSession(const DHBase & dhBase)252 int32_t DCameraProvider::OpenSession(const DHBase &dhBase)
253 {
254     DHLOGI("DCameraProvider::OpenSession for {devId: %{public}s, dhId: %{public}s}.",
255         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
256 
257     sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
258     if (callback == nullptr) {
259         DHLOGE("DCameraProvider::OpenSession, dcamera provider callback not found.");
260         return DCamRetCode::INVALID_ARGUMENT;
261     }
262 
263     return callback->OpenSession(dhBase);
264 }
265 
CloseSession(const DHBase & dhBase)266 int32_t DCameraProvider::CloseSession(const DHBase &dhBase)
267 {
268     DHLOGI("DCameraProvider::CloseSession for {devId: %{public}s, dhId: %{public}s}.",
269         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
270 
271     sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
272     if (callback == nullptr) {
273         DHLOGE("DCameraProvider::CloseSession, dcamera provider callback not found.");
274         return DCamRetCode::INVALID_ARGUMENT;
275     }
276 
277     return callback->CloseSession(dhBase);
278 }
279 
ConfigureStreams(const DHBase & dhBase,const std::vector<DCStreamInfo> & streamInfos)280 int32_t DCameraProvider::ConfigureStreams(const DHBase &dhBase, const std::vector<DCStreamInfo> &streamInfos)
281 {
282     DHLOGI("DCameraProvider::ConfigureStreams for {devId: %{public}s, dhId: %{public}s}.",
283         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
284 
285     sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
286     if (callback == nullptr) {
287         DHLOGE("DCameraProvider::ConfigStreams, dcamera provider callback not found.");
288         return DCamRetCode::INVALID_ARGUMENT;
289     }
290 
291     for (auto info = streamInfos.begin(); info != streamInfos.end(); info++) {
292         DHLOGI("ConfigureStreams: id=%{public}d, width=%{public}d, height=%{public}d, format=%{public}d, "
293                "type=%{public}d, mode=%{public}d.", info->streamId_, info->width_, info->height_, info->format_,
294                info->type_, info->mode_);
295     }
296     return callback->ConfigureStreams(dhBase, streamInfos);
297 }
298 
ReleaseStreams(const DHBase & dhBase,const std::vector<int> & streamIds)299 int32_t DCameraProvider::ReleaseStreams(const DHBase &dhBase, const std::vector<int> &streamIds)
300 {
301     DHLOGI("DCameraProvider::ReleaseStreams for {devId: %{public}s, dhId: %{public}s}.",
302         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
303 
304     sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
305     if (callback == nullptr) {
306         DHLOGE("DCameraProvider::ReleaseStreams, dcamera provider callback not found.");
307         return DCamRetCode::INVALID_ARGUMENT;
308     }
309 
310     std::string idString = "";
311     for (int id : streamIds) {
312         idString += (std::to_string(id) + ", ");
313     }
314     DHLOGI("ReleaseStreams: ids=[%{public}s].", idString.c_str());
315     return callback->ReleaseStreams(dhBase, streamIds);
316 }
317 
StartCapture(const DHBase & dhBase,const std::vector<DCCaptureInfo> & captureInfos)318 int32_t DCameraProvider::StartCapture(const DHBase &dhBase, const std::vector<DCCaptureInfo> &captureInfos)
319 {
320     DHLOGI("DCameraProvider::StartCapture for {devId: %{public}s, dhId: %{public}s}.",
321         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
322 
323     sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
324     if (callback == nullptr) {
325         DHLOGE("DCameraProvider::StartCapture, dcamera provider callback not found.");
326         return DCamRetCode::INVALID_ARGUMENT;
327     }
328 
329     for (auto info = captureInfos.begin(); info != captureInfos.end(); info++) {
330         std::string idString = "";
331         for (int id : info->streamIds_) {
332             idString += (std::to_string(id) + ", ");
333         }
334         DHLOGI("DCameraProvider::StartCapture: ids=[%{public}s], width=%{public}d, height=%{public}d, format="
335             "%{public}d, type=%{public}d, isCapture=%{public}d.",
336             (idString.empty() ? idString.c_str() : (idString.substr(0, idString.length() - INGNORE_STR_LEN)).c_str()),
337             info->width_, info->height_, info->format_, info->type_, info->isCapture_);
338     }
339     return callback->StartCapture(dhBase, captureInfos);
340 }
341 
StopCapture(const DHBase & dhBase,const std::vector<int> & streamIds)342 int32_t DCameraProvider::StopCapture(const DHBase &dhBase, const std::vector<int> &streamIds)
343 {
344     DHLOGI("DCameraProvider::StopCapture for {devId: %{public}s, dhId: %{public}s}.",
345         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
346 
347     sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
348     if (callback == nullptr) {
349         DHLOGE("DCameraProvider::StopCapture, dcamera provider callback not found.");
350         return DCamRetCode::INVALID_ARGUMENT;
351     }
352 
353     std::string idString = "";
354     for (int id : streamIds) {
355         idString += (std::to_string(id) + ", ");
356     }
357     DHLOGI("DCameraProvider::StopCapture: ids=[%{public}s].",
358         idString.empty() ? idString.c_str() : (idString.substr(0, idString.length() - INGNORE_STR_LEN)).c_str());
359     return callback->StopCapture(dhBase, streamIds);
360 }
361 
UpdateSettings(const DHBase & dhBase,const std::vector<DCameraSettings> & settings)362 int32_t DCameraProvider::UpdateSettings(const DHBase &dhBase, const std::vector<DCameraSettings> &settings)
363 {
364     DHLOGI("DCameraProvider::UpdateSettings for {devId: %{public}s, dhId: %{public}s}.",
365         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
366 
367     sptr<IDCameraProviderCallback> callback = GetCallbackBydhBase(dhBase);
368     if (callback == nullptr) {
369         DHLOGE("DCameraProvider::UpdateSettings, dcamera provider callback not found.");
370         return DCamRetCode::INVALID_ARGUMENT;
371     }
372 
373     return callback->UpdateSettings(dhBase, settings);
374 }
375 
IsDCameraSettingsInvalid(const DCameraSettings & result)376 bool DCameraProvider::IsDCameraSettingsInvalid(const DCameraSettings& result)
377 {
378     return result.value_.empty() || result.value_.length() > SETTING_VALUE_MAX_LENGTH;
379 }
380 
IsDCameraHDFEventInvalid(const DCameraHDFEvent & event)381 bool DCameraProvider::IsDCameraHDFEventInvalid(const DCameraHDFEvent& event)
382 {
383     return event.content_.length() > HDF_EVENT_CONTENT_MAX_LENGTH;
384 }
385 
GetCallbackBydhBase(const DHBase & dhBase)386 sptr<IDCameraProviderCallback> DCameraProvider::GetCallbackBydhBase(const DHBase &dhBase)
387 {
388     OHOS::sptr<DCameraDevice> device = GetDCameraDevice(dhBase);
389     if (device == nullptr) {
390         DHLOGE("DCameraProvider::GetCallbackBydhBase failed, dcamera device not found.");
391         return nullptr;
392     }
393     return device->GetProviderCallback();
394 }
395 
GetDCameraDevice(const DHBase & dhBase)396 OHOS::sptr<DCameraDevice> DCameraProvider::GetDCameraDevice(const DHBase &dhBase)
397 {
398     OHOS::sptr<DCameraHost> dCameraHost = DCameraHost::GetInstance();
399     if (dCameraHost == nullptr) {
400         DHLOGE("DCameraProvider::GetDCameraDevice, dcamera host is null.");
401         return nullptr;
402     }
403     return dCameraHost->GetDCameraDeviceByDHBase(dhBase);
404 }
405 } // namespace DistributedHardware
406 } // namespace OHOS
407