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_handler.h"
17
18 #include <functional>
19
20 #include "anonymous_string.h"
21 #include "avcodec_info.h"
22 #include "avcodec_list.h"
23 #include "dcamera_manager_callback.h"
24 #include "dcamera_utils_tools.h"
25 #include "distributed_camera_constants.h"
26 #include "distributed_camera_errno.h"
27 #include "distributed_hardware_log.h"
28 #include "metadata_utils.h"
29
30 namespace OHOS {
31 namespace DistributedHardware {
32 IMPLEMENT_SINGLE_INSTANCE(DCameraHandler);
33
34 const int32_t MAXWIDTHSIZE = 65535;
35
~DCameraHandler()36 DCameraHandler::~DCameraHandler()
37 {
38 DHLOGI("~DCameraHandler");
39 }
40
Initialize()41 int32_t DCameraHandler::Initialize()
42 {
43 DHLOGI("start");
44 cameraManager_ = CameraStandard::CameraManager::GetInstance();
45 if (cameraManager_ == nullptr) {
46 DHLOGE("cameraManager getInstance failed");
47 return DCAMERA_INIT_ERR;
48 }
49 std::shared_ptr<DCameraManagerCallback> cameraMgrCallback = std::make_shared<DCameraManagerCallback>();
50 cameraManager_->SetCallback(cameraMgrCallback);
51 DHLOGI("success");
52 return DCAMERA_OK;
53 }
54
QueryMeta()55 std::vector<DHItem> DCameraHandler::QueryMeta()
56 {
57 std::vector<DHItem> itemList;
58 CHECK_AND_RETURN_RET_LOG(cameraManager_ == nullptr, itemList, "cameraManager is null.");
59 std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
60 uint64_t listSize = static_cast<uint64_t>(cameraList.size());
61 DHLOGI("get %{public}" PRIu64" cameras", listSize);
62 if (cameraList.empty()) {
63 DHLOGE("no camera device");
64 return itemList;
65 }
66 for (auto& info : cameraList) {
67 if (info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN) {
68 DHLOGI("connection type: %{public}d", info->GetConnectionType());
69 continue;
70 }
71 DHLOGI("get %{public}s, position: %{public}d, cameraType: %{public}d",
72 GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
73 DHItem item;
74 if (CreateMetaDHItem(info, item) == DCAMERA_OK) {
75 itemList.emplace_back(item);
76 }
77 }
78 listSize = static_cast<uint64_t>(itemList.size());
79 DHLOGI("success, get %{public}" PRIu64" items", listSize);
80 return itemList;
81 }
82
Query()83 std::vector<DHItem> DCameraHandler::Query()
84 {
85 std::vector<DHItem> itemList;
86 CHECK_AND_RETURN_RET_LOG(cameraManager_ == nullptr, itemList, "cameraManager is null.");
87 std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
88 uint64_t listSize = static_cast<uint64_t>(cameraList.size());
89 DHLOGI("get %{public}" PRIu64" cameras", listSize);
90 if (cameraList.empty()) {
91 DHLOGE("no camera device");
92 return itemList;
93 }
94 for (auto& info : cameraList) {
95 if ((info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN)) {
96 DHLOGI("connection type: %{public}d", info->GetConnectionType());
97 continue;
98 }
99 DHLOGI("get %{public}s, position: %{public}d, cameraType: %{public}d",
100 GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
101 DHItem item;
102 if (CreateDHItem(info, item) == DCAMERA_OK) {
103 itemList.emplace_back(item);
104 }
105 }
106 listSize = static_cast<uint64_t>(itemList.size());
107 DHLOGI("success, get %{public}" PRIu64" items", listSize);
108 return itemList;
109 }
110
QueryExtraInfo()111 std::map<std::string, std::string> DCameraHandler::QueryExtraInfo()
112 {
113 DHLOGI("enter");
114 std::map<std::string, std::string> extraInfo;
115 return extraInfo;
116 }
117
IsSupportPlugin()118 bool DCameraHandler::IsSupportPlugin()
119 {
120 DHLOGI("enter");
121 return false;
122 }
123
RegisterPluginListener(std::shared_ptr<PluginListener> listener)124 void DCameraHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
125 {
126 DHLOGI("enter");
127 if (listener == nullptr) {
128 DHLOGE("DCameraHandler unregistering plugin listener");
129 }
130 pluginListener_ = listener;
131 }
132
UnRegisterPluginListener()133 void DCameraHandler::UnRegisterPluginListener()
134 {
135 DHLOGI("enter");
136 pluginListener_ = nullptr;
137 }
138
GetCameras()139 std::vector<std::string> DCameraHandler::GetCameras()
140 {
141 std::vector<std::string> cameras;
142 std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
143 uint64_t listSize = static_cast<uint64_t>(cameraList.size());
144 DHLOGI("get %{public}" PRIu64" cameras", listSize);
145 if (cameraList.empty()) {
146 DHLOGE("no camera device");
147 return cameras;
148 }
149 for (auto& info : cameraList) {
150 sptr<CameraStandard::CameraOutputCapability> capability = cameraManager_->GetSupportedOutputCapability(info);
151 if (capability == nullptr) {
152 DHLOGI("get supported capability is null");
153 continue;
154 }
155 if (info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN) {
156 DHLOGI("connection type: %{public}d", info->GetConnectionType());
157 continue;
158 }
159 DHLOGI("get %{public}s, position: %{public}d, cameraType: %{public}d",
160 GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
161 std::string dhId = CAMERA_ID_PREFIX + info->GetID();
162 cameras.emplace_back(dhId);
163 }
164 listSize = static_cast<uint64_t>(cameras.size());
165 DHLOGI("success, get %{public}" PRIu64" items", listSize);
166 return cameras;
167 }
168
CreateAVCodecList(cJSON * root)169 int32_t DCameraHandler::CreateAVCodecList(cJSON *root)
170 {
171 DHLOGI("Create avCodecList start");
172 std::shared_ptr<MediaAVCodec::AVCodecList> avCodecList = MediaAVCodec::AVCodecListFactory::CreateAVCodecList();
173 if (avCodecList == nullptr) {
174 DHLOGI("Create avCodecList failed");
175 return DCAMERA_BAD_VALUE;
176 }
177 const std::vector<std::string> encoderName = {std::string(MediaAVCodec::CodecMimeType::VIDEO_AVC),
178 std::string(MediaAVCodec::CodecMimeType::VIDEO_HEVC)};
179 cJSON *array = cJSON_CreateArray();
180 if (array == nullptr) {
181 DHLOGI("Create arrray failed");
182 return DCAMERA_BAD_VALUE;
183 }
184 cJSON_AddItemToObject(root, CAMERA_CODEC_TYPE_KEY.c_str(), array);
185 for (auto &coder : encoderName) {
186 MediaAVCodec::CapabilityData *capData = avCodecList->GetCapability(coder, true,
187 MediaAVCodec::AVCodecCategory::AVCODEC_HARDWARE);
188 if (capData == nullptr) {
189 DHLOGI("capData is nullptr");
190 return DCAMERA_BAD_VALUE;
191 }
192 std::string mimeType = capData->mimeType;
193 cJSON_AddItemToArray(array, cJSON_CreateString(mimeType.c_str()));
194 DHLOGI("codec name: %{public}s, mimeType: %{public}s", coder.c_str(), mimeType.c_str());
195 }
196 return DCAMERA_OK;
197 }
198
CreateMetaDHItem(sptr<CameraStandard::CameraDevice> & info,DHItem & item)199 int32_t DCameraHandler::CreateMetaDHItem(sptr<CameraStandard::CameraDevice>& info, DHItem& item)
200 {
201 std::string id = info->GetID();
202 item.dhId = CAMERA_ID_PREFIX + id;
203 item.subtype = "camera";
204 DHLOGI("camera id: %{public}s", GetAnonyString(id).c_str());
205
206 cJSON *root = cJSON_CreateObject();
207 CHECK_AND_RETURN_RET_LOG(root == nullptr, DCAMERA_BAD_VALUE, "Create cJSON object failed");
208 cJSON_AddStringToObject(root, CAMERA_METADATA_KEY.c_str(), CAMERA_METADATA_KEY.c_str());
209 char *jsonstr = cJSON_Print(root);
210 if (jsonstr == nullptr) {
211 cJSON_Delete(root);
212 return DCAMERA_BAD_VALUE;
213 }
214 item.attrs = jsonstr;
215 cJSON_free(jsonstr);
216 cJSON_Delete(root);
217 return DCAMERA_OK;
218 }
219
CreateDHItem(sptr<CameraStandard::CameraDevice> & info,DHItem & item)220 int32_t DCameraHandler::CreateDHItem(sptr<CameraStandard::CameraDevice>& info, DHItem& item)
221 {
222 std::string id = info->GetID();
223 item.dhId = CAMERA_ID_PREFIX + id;
224 item.subtype = "camera";
225
226 cJSON *root = cJSON_CreateObject();
227 CHECK_AND_RETURN_RET_LOG(root == nullptr, DCAMERA_BAD_VALUE, "Create cJSON object failed");
228 cJSON_AddStringToObject(root, CAMERA_PROTOCOL_VERSION_KEY.c_str(), CAMERA_PROTOCOL_VERSION_VALUE.c_str());
229 cJSON_AddStringToObject(root, CAMERA_POSITION_KEY.c_str(), GetCameraPosition(info->GetPosition()).c_str());
230 int32_t ret = CreateAVCodecList(root);
231 CHECK_AND_FREE_RETURN_RET_LOG(ret != DCAMERA_OK, DCAMERA_BAD_VALUE, root, "CreateAVCodecList failed");
232 sptr<CameraStandard::CameraOutputCapability> capability = cameraManager_->GetSupportedOutputCapability(info);
233 CHECK_AND_FREE_RETURN_RET_LOG(capability == nullptr, DCAMERA_BAD_VALUE, root, "get supported capability is null");
234 std::vector<CameraStandard::Profile> photoProfiles = capability->GetPhotoProfiles();
235 ConfigFormatphoto(SNAPSHOT_FRAME, root, photoProfiles);
236
237 std::vector<CameraStandard::Profile> previewProfiles = capability->GetPreviewProfiles();
238 ConfigFormatvideo(CONTINUOUS_FRAME, root, previewProfiles);
239
240 std::vector<CameraStandard::SceneMode> supportedModes = cameraManager_->GetSupportedModes(info);
241 if (!supportedModes.empty()) {
242 cJSON *modeArray = cJSON_CreateArray();
243 CHECK_AND_FREE_RETURN_RET_LOG(modeArray == nullptr, DCAMERA_BAD_VALUE, root, "Create modeArray object failed");
244 cJSON_AddItemToObject(root, CAMERA_SUPPORT_MODE.c_str(), modeArray);
245 for (auto &mode : supportedModes) {
246 DHLOGI("The camera id: %{public}s, The supportedModes is : %{public}d", GetAnonyString(id).c_str(), mode);
247 cJSON_AddItemToArray(modeArray, cJSON_CreateNumber(mode));
248 auto capability = cameraManager_->GetSupportedOutputCapability(info, mode);
249 CHECK_AND_FREE_RETURN_RET_LOG(
250 capability == nullptr, DCAMERA_BAD_VALUE, root, "supported capability is null");
251 cJSON *modeData = cJSON_CreateObject();
252 CHECK_AND_FREE_RETURN_RET_LOG(modeData == nullptr, DCAMERA_BAD_VALUE, root, "Create cJSON object failed");
253 std::vector<CameraStandard::Profile> photoProfiles = capability->GetPhotoProfiles();
254 ConfigFormatphoto(SNAPSHOT_FRAME, modeData, photoProfiles);
255
256 std::vector<CameraStandard::Profile> previewProfiles = capability->GetPreviewProfiles();
257 ConfigFormatvideo(CONTINUOUS_FRAME, modeData, previewProfiles);
258
259 cJSON_AddItemToObject(root, std::to_string(mode).c_str(), modeData);
260 }
261 }
262
263 ret = CreateMeatdataStr(info, root);
264 CHECK_AND_FREE_RETURN_RET_LOG(ret != DCAMERA_OK, DCAMERA_BAD_VALUE, root, "CreateMeatdataStr failed");
265 char *jsonstr = cJSON_Print(root);
266 CHECK_AND_FREE_RETURN_RET_LOG(jsonstr == nullptr, DCAMERA_BAD_VALUE, root, "jsonstr is null");
267
268 item.attrs = jsonstr;
269 cJSON_free(jsonstr);
270 cJSON_Delete(root);
271 return DCAMERA_OK;
272 }
273
CreateMeatdataStr(sptr<CameraStandard::CameraDevice> & info,cJSON * root)274 int32_t DCameraHandler::CreateMeatdataStr(sptr<CameraStandard::CameraDevice>& info, cJSON *root)
275 {
276 sptr<CameraStandard::CameraInput> cameraInput = nullptr;
277 int32_t rv = cameraManager_->CreateCameraInput(info, &cameraInput);
278 if (rv != DCAMERA_OK) {
279 DHLOGE("create cameraInput failed");
280 return DCAMERA_BAD_VALUE;
281 }
282
283 std::hash<std::string> h;
284 std::string abilityStr = cameraInput->GetCameraSettings();
285 DHLOGI("abilityString hash: %{public}zu, length: %{public}zu", h(abilityStr), abilityStr.length());
286
287 std::string encStr = Base64Encode(reinterpret_cast<const unsigned char*>(abilityStr.c_str()), abilityStr.length());
288 DHLOGI("encodeString hash: %zu, length: %zu", h(encStr), encStr.length());
289 cJSON_AddStringToObject(root, CAMERA_METADATA_KEY.c_str(), encStr.c_str());
290 CHECK_AND_LOG(cameraInput->Release() != DCAMERA_OK, "cameraInput Release failed");
291 return DCAMERA_OK;
292 }
293
GetCameraPosition(CameraStandard::CameraPosition position)294 std::string DCameraHandler::GetCameraPosition(CameraStandard::CameraPosition position)
295 {
296 DHLOGI("position: %{public}d", position);
297 std::string ret = "";
298 switch (position) {
299 case CameraStandard::CameraPosition::CAMERA_POSITION_BACK: {
300 ret = CAMERA_POSITION_BACK;
301 break;
302 }
303 case CameraStandard::CameraPosition::CAMERA_POSITION_FRONT: {
304 ret = CAMERA_POSITION_FRONT;
305 break;
306 }
307 case CameraStandard::CameraPosition::CAMERA_POSITION_UNSPECIFIED: {
308 ret = CAMERA_POSITION_UNSPECIFIED;
309 break;
310 }
311 default: {
312 DHLOGE("unknown camera position");
313 break;
314 }
315 }
316 DHLOGI("success ret: %{public}s", ret.c_str());
317 return ret;
318 }
319
ProcessProfile(const DCStreamType type,std::map<std::string,std::list<std::string>> & formatMap,std::vector<CameraStandard::Profile> & profileList,std::set<int32_t> & formatSet)320 void DCameraHandler::ProcessProfile(const DCStreamType type, std::map<std::string, std::list<std::string>>& formatMap,
321 std::vector<CameraStandard::Profile>& profileList, std::set<int32_t>& formatSet)
322 {
323 for (auto& profile : profileList) {
324 CameraStandard::CameraFormat format = profile.GetCameraFormat();
325 CameraStandard::Size picSize = profile.GetSize();
326 int32_t dformat = CovertToDcameraFormat(format);
327 if (dformat == INVALID_FORMAT) {
328 continue;
329 }
330 formatSet.insert(dformat);
331 DHLOGI("width: %{public}d, height: %{public}d, format: %{public}d", picSize.width, picSize.height, dformat);
332 std::string formatName = std::to_string(dformat);
333 if (IsValid(type, picSize)) {
334 std::string resolutionValue = std::to_string(picSize.width) + "*" + std::to_string(picSize.height);
335 formatMap[formatName].push_back(resolutionValue);
336 }
337 }
338 }
339
ConfigFormatphoto(const DCStreamType type,cJSON * root,std::vector<CameraStandard::Profile> & profileList)340 void DCameraHandler::ConfigFormatphoto(const DCStreamType type, cJSON* root,
341 std::vector<CameraStandard::Profile>& profileList)
342 {
343 DHLOGI("type: %{public}d, size: %{public}zu", type, profileList.size());
344 std::set<int32_t> formatSet;
345 cJSON* formatphotoObj = cJSON_CreateObject();
346 if (formatphotoObj == nullptr) {
347 return;
348 }
349 cJSON_AddItemToObject(root, CAMERA_FORMAT_PHOTO.c_str(), formatphotoObj);
350 std::map<std::string, std::list<std::string>> formatMap;
351 ProcessProfile(type, formatMap, profileList, formatSet);
352 cJSON* resolutionObj = cJSON_CreateObject();
353 if (resolutionObj == nullptr) {
354 return;
355 }
356 for (auto &pair : formatMap) {
357 cJSON* array = cJSON_CreateArray();
358 cJSON_AddItemToObject(resolutionObj, pair.first.c_str(), array);
359 for (auto &value : pair.second) {
360 cJSON_AddItemToArray(array, cJSON_CreateString(value.c_str()));
361 }
362 }
363 cJSON_AddItemToObject(formatphotoObj, CAMERA_RESOLUTION_KEY.c_str(), resolutionObj);
364 cJSON* array = cJSON_CreateArray();
365 if (array == nullptr) {
366 return;
367 }
368 for (auto format : formatSet) {
369 cJSON_AddItemToArray(array, cJSON_CreateNumber(format));
370 }
371 cJSON_AddItemToObject(formatphotoObj, CAMERA_FORMAT_KEY.c_str(), array);
372 }
373
ConfigFormatvideo(const DCStreamType type,cJSON * root,std::vector<CameraStandard::Profile> & profileList)374 void DCameraHandler::ConfigFormatvideo(const DCStreamType type, cJSON* root,
375 std::vector<CameraStandard::Profile>& profileList)
376 {
377 DHLOGI("type: %d, size: %{public}zu", type, profileList.size());
378 std::set<int32_t> formatSet;
379 cJSON* formatpreviewObj = cJSON_CreateObject();
380 if (formatpreviewObj == nullptr) {
381 return;
382 }
383 cJSON_AddItemToObject(root, CAMERA_FORMAT_PREVIEW.c_str(), formatpreviewObj);
384 std::map<std::string, std::list<std::string>> formatMap;
385 ProcessProfile(type, formatMap, profileList, formatSet);
386 cJSON* resolutionObj = cJSON_CreateObject();
387 if (resolutionObj == nullptr) {
388 return;
389 }
390 for (auto &pair : formatMap) {
391 cJSON* array = cJSON_CreateArray();
392 cJSON_AddItemToObject(resolutionObj, pair.first.c_str(), array);
393 for (auto &value : pair.second) {
394 cJSON_AddItemToArray(array, cJSON_CreateString(value.c_str()));
395 }
396 }
397 cJSON_AddItemToObject(formatpreviewObj, CAMERA_RESOLUTION_KEY.c_str(), resolutionObj);
398 cJSON* array = cJSON_CreateArray();
399 if (array == nullptr) {
400 return;
401 }
402 for (auto format : formatSet) {
403 cJSON_AddItemToArray(array, cJSON_CreateNumber(format));
404 }
405 cJSON_AddItemToObject(formatpreviewObj, CAMERA_FORMAT_KEY.c_str(), array);
406 cJSON* formatvideoObj = cJSON_Duplicate(formatpreviewObj, 1);
407 cJSON_AddItemToObject(root, CAMERA_FORMAT_VIDEO.c_str(), formatvideoObj);
408 }
409
CovertToDcameraFormat(CameraStandard::CameraFormat format)410 int32_t DCameraHandler::CovertToDcameraFormat(CameraStandard::CameraFormat format)
411 {
412 DHLOGI("format: %{public}d", format);
413 int32_t ret = INVALID_FORMAT;
414 switch (format) {
415 case CameraStandard::CameraFormat::CAMERA_FORMAT_RGBA_8888:
416 ret = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888;
417 break;
418 case CameraStandard::CameraFormat::CAMERA_FORMAT_YCBCR_420_888:
419 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCBCR_420_888;
420 break;
421 case CameraStandard::CameraFormat::CAMERA_FORMAT_YUV_420_SP:
422 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_420_SP;
423 break;
424 case CameraStandard::CameraFormat::CAMERA_FORMAT_JPEG:
425 ret = camera_format_t::OHOS_CAMERA_FORMAT_JPEG;
426 break;
427 case CameraStandard::CameraFormat::CAMERA_FORMAT_YCBCR_P010:
428 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCBCR_P010;
429 break;
430 case CameraStandard::CameraFormat::CAMERA_FORMAT_YCRCB_P010:
431 ret = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_P010;
432 break;
433 default:
434 DHLOGE("invalid camera format");
435 break;
436 }
437 return ret;
438 }
439
IsValid(const DCStreamType type,const CameraStandard::Size & size)440 bool DCameraHandler::IsValid(const DCStreamType type, const CameraStandard::Size& size)
441 {
442 bool ret = false;
443 switch (type) {
444 case CONTINUOUS_FRAME: {
445 ret = (size.width >= RESOLUTION_MIN_WIDTH) &&
446 (size.height >= RESOLUTION_MIN_HEIGHT) &&
447 (size.width <= RESOLUTION_MAX_WIDTH_CONTINUOUS) &&
448 (size.height <= RESOLUTION_MAX_HEIGHT_CONTINUOUS);
449 break;
450 }
451 case SNAPSHOT_FRAME: {
452 if (size.width > MAXWIDTHSIZE) {
453 DHLOGE("size width out of range.");
454 return ret;
455 }
456 uint64_t dcResolution = static_cast<uint64_t>(size.width * size.width);
457 uint64_t dcMaxResolution = static_cast<uint64_t>(RESOLUTION_MAX_WIDTH_SNAPSHOT *
458 RESOLUTION_MAX_HEIGHT_SNAPSHOT);
459 uint64_t dcMinResolution = static_cast<uint64_t>(RESOLUTION_MIN_WIDTH *
460 RESOLUTION_MIN_HEIGHT);
461 ret = (dcResolution >= dcMinResolution) && (dcResolution <= dcMaxResolution);
462 break;
463 }
464 default: {
465 DHLOGE("unknown stream type");
466 break;
467 }
468 }
469 return ret;
470 }
471
GetHardwareHandler()472 IHardwareHandler* GetHardwareHandler()
473 {
474 DHLOGI("DCameraHandler::GetHardwareHandler");
475 return &DCameraHandler::GetInstance();
476 }
477 } // namespace DistributedHardware
478 } // namespace OHOS