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